我写了一个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
- $
为什么会这样,我该如何解决?
在您的脚本中,ssh作业获取与读取行相同的标准输入,并且在您的情况下恰好在第一次调用时占用所有行.因此读取线只能看到
输入的第一行.
输入的第一行.
解决方案:关闭sdin的stdin,或者从/ dev / null更好地重定向. (有些计划
不喜欢stdin关闭)
- 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
如果您不想为/ dev / null重定向循环中的每个作业,您还可以尝试以下方法之一:
- 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