且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-11 20:46:22

在您的脚本中,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