在 bash 脚本中通过 ssh 在远程主机上执行命令 [英] Execute a command on remote hosts via ssh from inside a bash script
问题描述
我写了一个 bash 脚本,它应该从文件中读取用户名和 IP 地址,并通过 ssh 对它们执行命令.
I wrote a bash script which is supposed to read usernames and IP addresses from a file and execute a command on them via ssh.
这是hosts.txt:
This is hosts.txt :
user1 192.168.56.232
user2 192.168.56.233
这是 myScript.sh :
This is 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
问题是第一个主机完成后执行似乎停止了.这是输出:
The problem is that execution seems to stop after the first host is done. This is the output:
$ ./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
$
为什么会这样,我该如何解决?
Why does is behave like this, and how can i fix it?
推荐答案
在您的脚本中,ssh
作业获得与 read 行
相同的标准输入,并且在您的case 碰巧吃掉了第一次调用的所有行.所以 read line
只能看到输入的第一行.
In your script, the ssh
job gets the same stdin as the read line
, and in your case happens to eat up all the lines on the first invocation. So read line
only gets to see
the very first line of the input.
解决方案:关闭 ssh
的 stdin,或者更好地从 /dev/null
重定向.(一些程序不喜欢关闭标准输入)
Solution: Close stdin for ssh
, or better redirect from /dev/null
. (Some programs
don't like having stdin closed)
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
' "$line"
done < hosts.txt
如果您不想为循环内的每个作业都从/dev/null 重定向,您也可以尝试以下方法之一:
If you don't want to redirect from /dev/null for every single job inside the loop, you can also try one of these:
while read line
do
{
commands...
} </dev/null # Redirect stdin from /dev/null for all
# commands inside the braces
done < hosts.txt
# In the following, let's not override the original stdin. Open hosts.txt on fd3
# instead
while read line <&3 # execute read command with fd0 (stdin) backed up from fd3
do
commands... # inside, you still have the original stdin
# (maybe the terminal) from outside, which can be practical.
done 3< hosts.txt # make hosts.txt available as fd3 for all commands in the
# loop (so fd0 (stdin) will be unaffected)
# totally safe way: close fd3 for all inner commands at once
while read line <&3
do
{
commands...
} 3<&-
done 3< hosts.txt
这篇关于在 bash 脚本中通过 ssh 在远程主机上执行命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!