在bash脚本中通过ssh在远程主机上执行命令

时间:2011-12-04 15:04:02

标签: bash shell ssh openssh

我写了一个bash脚本,它应该从文件中读取用户名和IP地址,并通过ssh对它们执行命令。

这是hosts.txt:

user1 192.168.56.232
user2 192.168.56.233

这是myScript.sh:

cmd="ls -l"

while read line
do
   set $line
   echo "HOST:" $1@$2
   ssh $1@$2 $cmd
   exitStatus=$?
   echo "Exit Status: " $exitStatus
done < hosts.txt

问题是执行似乎在第一个主机完成后停止。这是输出:

$ ./myScript.sh
HOST: user1@192.168.56.232
total 2748
drwxr-xr-x 2 user1 user1    4096 2011-11-15 20:01 Desktop
drwxr-xr-x 2 user1 user1    4096 2011-11-10 20:37 Documents
...
drwxr-xr-x 2 user1 user1    4096 2011-11-10 20:37 Videos
Exit Status:  0
$

为什么表现得像这样,我该如何解决?

4 个答案:

答案 0 :(得分:8)

在您的脚本中,ssh作业获得与read line相同的标准输入,并且在您的情况下恰好会占用第一次调用的所有行。所以read line只能看到 输入的第一行。

解决方案:关闭[{1}}的标准输入,或者更好地从ssh重定向。 (有些计划 不喜欢stdin关闭)

/dev/null

如果您不想为/ dev / null重定向循环中的每个作业,您还可以尝试以下方法之一:

while read line
do
    ssh server somecommand </dev/null    # Redirect stdin from /dev/null
                                         # for ssh command
                                         # (Does not affect the other commands)
    printf '%s\n' "$line"
done < hosts.txt

答案 1 :(得分:4)

您遇到的问题是SSH进程占用了所有stdin,因此在第一个ssh命令运行后,read没有看到任何输入。您可以使用-n标志来阻止这种情况发生,或者您可以将/ dev / null重定向到ssh命令的stdin。

有关详细信息,请参阅以下内容: http://mywiki.wooledge.org/BashFAQ/089

答案 2 :(得分:3)

确保使用ssh无法从hosts.txt中读取ssh -n命令

答案 3 :(得分:1)

我有一种感觉,你的问题是不必要的冗长......

基本上你应该可以用以下方法重现问题:

while read line
do
   echo $line
done < hosts.txt

哪个应该可以正常工作..你编辑正确的文件吗?它中有特殊字符吗?用适当的编辑器检查(例如:vim)。