在 bash 脚本中通过 ssh 在远程主机上执行命令 [英] Execute a command on remote hosts via ssh from inside a bash script

查看:45
本文介绍了在 bash 脚本中通过 ssh 在远程主机上执行命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆