在shell脚本中的while循环里,通过ssh调用远程主机的时候,while循环运行一次就退出了……
1.示例代码
#!/bin/bash
echo -e "1\n2\n3" | while read num
do
ssh -i /root/.ssh/id_rsa root@172.16.1.123 "hostname"
echo $num
done
### 运行结果:
leidy_123
1
2.原因分析
while中使用重定向机制,循环的信息都已经读入并重定向给了整个while语句,所以当我们在while循环中再一次调用read语句,就会读取到下一条记录,但是,因为ssh会读取stdin中存在的缓存,调用完ssh语句后,输入缓存中已经都被读完了,当read语句再读的时候当然也就读不到纪录,循环也就退出了。
3.解决方案
3.1 使用for循环替代while循环
由于for循环没有一次性的把循环内容缓存进来,所以就不存在上述的问题:
#!/bin/bash
for num in 1 2 3
do
ssh -i /root/.ssh/id_rsa root@172.16.1.123 "hostname"
echo $num
done
### 运行结果:
leidy_123
1
leidy_123
2
leidy_123
3
3.2 禁止ssh从stdin中读取缓存数据
通过将/dev/null 重定向到ssh的stdin,从而达到禁止ssh读取while循环中stdin的目的。
#!/bin/bash
echo -e "1\n2\n3" | while read num
do
ssh -n -i /root/.ssh/id_rsa root@172.16.1.123 "hostname"
echo $num
done
### 运行结果:
leidy_123
1
leidy_123
2
leidy_123
3
或者:
#!/bin/bash
echo -e "1\n2\n3" | while read num
do
ssh -i /root/.ssh/id_rsa root@172.16.1.123 "hostname" < /dev/null
echo $num
done
### 运行结果:
leidy_123
1
leidy_123
2
leidy_123
3
两者原理上是相同的,可以参考ssh的man page中-n选项的解释:
Redirects stdin from /dev/null (actually, prevents reading from stdin).
暂无评论