while read line语句中ssh远程执行命令,只运行了一次。
目的:批量修改主机信息。
有一个host.txt文件,记录服务器ip,已经配置好秘钥登陆。如:
[root@m ~]# cat host.txt 192.168.10.71 192.168.10.72 192.168.10.73
现在想批量修改主机名,比如idc-001、idc-002 …,后面3位是数字
# 通过 expr 表达式实现shell中进行数学运算
# 通过 printf 格式化字符串,不足3位用0补全
# 先拼接出来主机名,再进一步添加修改功能
[root@m ~]# cat b #!/bin/bash str="idc-" n=1 while read ip do host_num=`printf "%03d" $n` hostname=$str$host_num echo $ip $hostname n=`expr $n + 1` done < host.txt
# 执行结果没问题
[root@m ~]# sh b 192.168.10.71 idc-001 192.168.10.72 idc-002 192.168.10.73 idc-003
# 下一步就要通过ssh登陆实现修改主机名
[root@m ~]# cat b #!/bin/bash str="idc-" n=1 while read ip do host_num=`printf "%03d" $n` hostname=$str$host_num echo $ip $hostname ssh -o "StrictHostKeyChecking no" root@$ip "echo $hostname > /etc/hostname && hostname $hostname" n=`expr $n + 1` done < host.txt
# 运行
[root@m ~]# sh b 192.168.10.71 idc-001 [root@m ~]#
就执行了一行,退出了。去看71这台机器是修改成功了,但是72、73仍旧没变化。怀疑问题出在ssh上。
原因:
ssh中有个参数为 -n 通过man看到解释:
Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background. A common trick is to use this to run X11 programs on a remote machine. For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel. The ssh program will be put in the background. (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.)
即ssh从stdin中读取了while read line的内容,导致while语句没有输入了,就执行完了。
-n的作用就是阻止ssh读取标准输入,为了验证这个结论,修改下host.txt文件,并且把ssh要执行的命令去掉。
[root@m ~]# cat b #!/bin/bash str="idc-" n=1 while read ip do host_num=`printf "%03d" $n` hostname=$str$host_num echo $ip $hostname ssh -o "StrictHostKeyChecking no" root@$ip # 去掉了后面的命令 n=`expr $n + 1` done < host.txt [root@m ~]# cat host.txt 最后两行为两条系统命令 192.168.10.71 uname -r date
# 执行
[root@m ~]# sh b 192.168.10.71 idc-001 Pseudo-terminal will not be allocated because stdin is not a terminal. 3.10.0-514.el7.x86_64 Wed Apr 17 16:44:58 CST 2019
可以看到内核版本和日期,说明ssh从标准输入读取了内容做为命令执行了,导致while标准输入为空,最后退出。
# 修改后正确姿势,添加-n参数
#!/bin/bash str="idc-" n=1 while read ip do host_num=`printf "%03d" $n` hostname=$str$host_num echo $ip $hostname ssh -n -o "StrictHostKeyChecking no" root@$ip "hostname $hostname && echo $hostname > /etc/hostname" n=`expr $n + 1` done < host.txt
# 执行结果
[root@m ~]# sh b 192.168.10.71 idc-001 192.168.10.72 idc-002 192.168.10.73 idc-003
再去看72、73两台机器正确修改了。
原创文章,转载请注明。本文链接地址: https://www.rootop.org/pages/4311.html