2010-07-09 22 views
2

我有一个快速脚本在每个使用ssh的服务器上运行命令(我确信有很多更好的方法可以做到这一点,但它的目的只是快速工作!!)。对于test1等,没有服务器,所以脚本继续,如果pubkey认证失败,脚本也会继续。但是,如果脚本连接,日期打印,但ssh循环终止...在我的bash循环在一些服务器的列表中,如果ssh连接bash脚本退出

#!/bin/bash -x 

cat <<EOF | 
##file servers 
test1 
test2 
server1 
server2 
EOF 
while read line 
do 
if [ "${line:0:1}" != "#" ]; then 

ssh -q -oPasswordAuthentication=no -i id_dsa [email protected]${line} date 

fi 
done 

echo read line must have exited 

输出是这样的;

+ cat 
+ read line 
+ '[' t '!=' '#' ']' 
+ ssh -q -oPasswordAuthentication=no -i id_dsa [email protected] date 
+ read line 
+ '[' t '!=' '#' ']' 
+ ssh -q -oPasswordAuthentication=no -i id_dsa [email protected] date 
+ read line1 
+ '[' s '!=' '#' ']' 
+ ssh -q -oPasswordAuthentication=no -i id_dsa [email protected] date 
Fri Jul 9 09:04:16 PDT 2010 
+ read line 
+ echo read line must have exited 
read line must have exited`enter code here` 

与成功返回的ssh命令有关的事情是搞乱了循环或var的条件...有什么建议,为什么?

回答

9

你应该通过-n标志为SSH,以防止它与标准输入搞乱:

ssh -n -q -oPasswordAuthentication=no -i id_dsa [email protected]${line} date 

我测试了这个与我自己的服务器和转载问题,加入-n解决它。由于SSH手册页说:

从/ dev重定向标准输入/空

在您的例子(实际上,可防止 标准输入读取),SSH必须从标准输入读取,这打乱了你在循环中阅读。

+0

欢呼声。测试,并去! – 2010-07-09 16:37:59

0

我认为原因是因为ssh在你的bash脚本中被分支和执行,脚本的标准输入被重新打开,所以你的read同时终止。请尝试重新各具特色如下:

for line in test1 test2 server1 server2 
do 
    if [ "${line:0:1}" != "#" ]; then 
     ssh -q -oPasswordAuthentication=no -i id_dsa [email protected]${line} date 
    fi 
done 

或者也许在一个子shell这样的运行SSH:

(ssh -q -oPasswordAuthentication=no -i id_dsa [email protected]${line} date) 
+0

用于循环它们并不是我想要做的,但我想我的下一步应该是将每行粘贴在一个数组中,以便我可以处理需要保持stdin管道循环。 有趣的是,subhell仍然抓住stdin并关闭管道 – 2010-07-09 16:40:14