ubl007
作者ubl007·2023-09-13 23:22
私有云高级交付(DTA方向)·百度智能云

通过 while循环体对远程主机进行遍历性ssh登录并执行目标指令

字数 7286阅读 1142评论 1赞 4

实现方法:

一 对 ssh 命令使用选项“-n”

二 使用 for循环遍历替代 while循环遍历

三 对 while 循环体使用 exec描述符

问题的表现现象:

while循环体只执行了目标文件中的第一行内容便推出循环了。
此现象也称作“while循环吃行现象”。

如以下实例所示:

[root@localhost centos7-00]# cat /etc/hosts

192.168.136.145 slave0

192.168.136.152 slave1

[root@localhost centos7-00]#

[root@localhost centos7-00]# cat /etc/hosts | while read hang;do server=echo ${hang} | awk -F " " '{print $1}' && name=echo ${hang} | awk -F " " '{print $2}' && ssh root@${server} "ip a";done

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

inet 127.0.0.1/8 scope host lo

valid_lft forever preferred_lft forever

inet6 ::1/128 scope host

valid_lft forever preferred_lft forever

2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

link/ether 00:0c:29:6d:22:15 brd ff:ff:ff:ff:ff:ff

inet 192.168.136.145/24 brd 192.168.136.255 scope global noprefixroute dynamic ens33

valid_lft 1143sec preferred_lft 1143sec

inet6 fe80::e212:a166:2a5:ffdc/64 scope link noprefixroute

valid_lft forever preferred_lft forever

3: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0

valid_lft forever preferred_lft forever

4: virbr0-nic: mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

[root@localhost centos7-00]#
[root@localhost centos7-00]# vim test.sh

[root@localhost centos7-00]#

[root@localhost centos7-00]# cat test.sh

cat /etc/hosts | while read hang

do

server=echo ${hang} | awk -F " " '{print $1}'

name=echo ${hang} | awk -F " " '{print $2}'

ssh root@${server} "ip a"

done

[root@localhost centos7-00]#

[root@localhost centos7-00]# sh -x test.sh

  • cat /etc/hosts
  • read hang

++ echo 192.168.136.145 slave0

++ awk -F ' ' '{print $1}'

  • server=192.168.136.145

++ awk -F ' ' '{print $2}'

++ echo 192.168.136.145 slave0

  • name=slave0
  • ssh -n root@192.168.136.145 'ip a'

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

inet 127.0.0.1/8 scope host lo

valid_lft forever preferred_lft forever

inet6 ::1/128 scope host

valid_lft forever preferred_lft forever

2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

link/ether 00:0c:29:6d:22:15 brd ff:ff:ff:ff:ff:ff

inet 192.168.136.145/24 brd 192.168.136.255 scope global noprefixroute dynamic ens33

valid_lft 1642sec preferred_lft 1642sec

inet6 fe80::e212:a166:2a5:ffdc/64 scope link noprefixroute

valid_lft forever preferred_lft forever

3: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0

valid_lft forever preferred_lft forever

4: virbr0-nic: mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

  • read hang

++ echo 192.168.136.152 slave1

++ awk -F ' ' '{print $1}'

  • server=192.168.136.152

++ echo 192.168.136.152 slave1

++ awk -F ' ' '{print $2}'

  • name=slave1
  • ssh -n root@192.168.136.152 'ip a'

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

inet 127.0.0.1/8 scope host lo

valid_lft forever preferred_lft forever

inet6 ::1/128 scope host

valid_lft forever preferred_lft forever

2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

link/ether 00:0c:29:4c:90:50 brd ff:ff:ff:ff:ff:ff

inet 192.168.136.152/24 brd 192.168.136.255 scope global noprefixroute dynamic ens33

valid_lft 1421sec preferred_lft 1421sec

inet6 fe80::e212:a166:2a5:ffdc/64 scope link tentative noprefixroute dadfailed

valid_lft forever preferred_lft forever

inet6 fe80::1018:25e5:682e:fa55/64 scope link noprefixroute

valid_lft forever preferred_lft forever

3: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0

valid_lft forever preferred_lft forever

4: virbr0-nic: mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

  • read hang

[root@localhost centos7-00]#

产生此现象的原因:

while 使用了重定向机制,这个重定向是针对while循环快整体的,/etc/hosts 中的行信息被读取并重定向到了while循环块中,当while中再次调用read语句是就会读取到文件 /etc/hosts 中的下一条记录。while中使用ssh时,为了禁止ssh读取行内容后增加一个 “< /dev.null”,会将ssh的输入进行重定向。 While循环块中使用 sed 命令也有此种现象。

解决示例参考:

[root@localhost centos7-00]#

[root@localhost centos7-00]# cat test.sh

cat /etc/hosts | while read hang

do

server=echo ${hang} | awk -F " " '{print $1}'

name=echo ${hang} | awk -F " " '{print $2}'

ssh -n root@${server} "ip a"

done

[root@localhost centos7-00]#

[root@localhost centos7-00]#

[root@localhost centos7-00]# sh -x test.sh

  • cat /etc/hosts
  • read hang

++ echo 192.168.136.145 slave0

++ awk -F ' ' '{print $1}'

  • server=192.168.136.145

++ awk -F ' ' '{print $2}'

++ echo 192.168.136.145 slave0

  • name=slave0
  • ssh -n root@192.168.136.145 'ip a'

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

inet 127.0.0.1/8 scope host lo

valid_lft forever preferred_lft forever

inet6 ::1/128 scope host

valid_lft forever preferred_lft forever

2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

link/ether 00:0c:29:6d:22:15 brd ff:ff:ff:ff:ff:ff

inet 192.168.136.145/24 brd 192.168.136.255 scope global noprefixroute dynamic ens33

valid_lft 1642sec preferred_lft 1642sec

inet6 fe80::e212:a166:2a5:ffdc/64 scope link noprefixroute

valid_lft forever preferred_lft forever

3: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0

valid_lft forever preferred_lft forever

4: virbr0-nic: mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

  • read hang

++ echo 192.168.136.152 slave1

++ awk -F ' ' '{print $1}'

  • server=192.168.136.152

++ echo 192.168.136.152 slave1

++ awk -F ' ' '{print $2}'

  • name=slave1
  • ssh -n root@192.168.136.152 'ip a'

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

inet 127.0.0.1/8 scope host lo

valid_lft forever preferred_lft forever

inet6 ::1/128 scope host

valid_lft forever preferred_lft forever

2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

link/ether 00:0c:29:4c:90:50 brd ff:ff:ff:ff:ff:ff

inet 192.168.136.152/24 brd 192.168.136.255 scope global noprefixroute dynamic ens33

valid_lft 1421sec preferred_lft 1421sec

inet6 fe80::e212:a166:2a5:ffdc/64 scope link tentative noprefixroute dadfailed

valid_lft forever preferred_lft forever

inet6 fe80::1018:25e5:682e:fa55/64 scope link noprefixroute

valid_lft forever preferred_lft forever

3: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0

valid_lft forever preferred_lft forever

4: virbr0-nic: mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000

link/ether 52:54:00:c8:2c:80 brd ff:ff:ff:ff:ff:ff

  • read hang

[root@localhost centos7-00]#

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

4

添加新评论1 条评论

热心冰块热心冰块项目经理浪潮INSPUR
2023-09-15 15:50
大哥,你这牛啊,当初我就是看这Shell的语法复杂及代码太难读才转投了Python。抱歉我没看到10行就直接翻页到底了发评论了。

ubl007@热心冰块 谬赞了,只是在执行命令式出错了,扒拉了扒拉官方文档的解释,给记录了下来

2023-09-16 13:33
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广