【问题标题】:Failed to run scripts in multiple remote host by sshssh 无法在多个远程主机上运行脚本
【发布时间】:2016-08-03 17:00:14
【问题描述】:

我写了一个deployAll.sh,逐行读取ip_host.list,然后为所有远程主机添加组,

当我运行时:sh deployAll.sh

结果:

Group is added to 172.25.30.11

非预期结果:

Group is added to 172.25.30.11
Group is added to 172.25.30.12  
Group is added to 172.25.30.13

为什么它只执行第一个?请帮忙,非常感谢!

deployAll.sh

    #!/bin/bash

    function deployAll()
    {
        while read line;do
            IFS=';' read -ra ipandhost<<< "$line"
            ssh "${ipandhost[0]}" "groupadd -g 1011 test"
            printf "Group is added to ${ipandhost[0]}\n"
        done < ip_host.list
    }

deployAll

ip_host.list

172.25.30.11;test-30-11
172.25.30.12;test-30-12
172.25.30.13;test-30-13

【问题讨论】:

  • 奇怪,它对我有用。发布echo $BASH_VERSION 的结果以及当您使用bash -x deployAll.sh 运行脚本时。
  • 你真的很想看看 Ansible 项目:docs.ansible.com/ansible/quickstart.html

标签: bash ssh


【解决方案1】:

我的解决方案是通过 ssh-keygen 命令生成 ssh 密钥并替换现有的公钥文件(如果有)。之后将继续安装。

【讨论】:

    【解决方案2】:

    如果没有ssh 命令(这在我的网络上没有意义),我会得到预期的输出,所以我怀疑ssh 命令正在吞噬剩余的标准输入。您应该使用-n 标志来阻止sshstdin 读取(相当于从/dev/null 重定向stdin):

    ssh -n "${ipandhost[0]}" "groupadd -g 1011 test"
    

    ssh "${ipandhost[0]}" "groupadd -g 1011 test" < /dev/null
    

    另见How to keep script from swallowing all of stdin?

    【讨论】:

      【解决方案3】:

      这是一个常见的问题,由 ssh 的特殊行为引起,它吸收 stdin,使循环饿死(即 while read line;do ...;done

      请参阅Bash FAQ 89 详细讨论此主题。

      我也刚刚回答(并解决了)关于ffmpeg 的类似问题,在这种情况下与ssh 的行为相同。这里:When reading a file line by line, I only get to execute ffmpeg on the first line

      TL;DR :

      有三个主要选项:

      • 使用ssh-n 选项。引用自man ssh
        -n     Redirects  stdin  from  /dev/null  (actually,  prevents reading from stdin).  This must be used when ssh is run in the background.  A common trick is to use this to run X11 programs on a remote
                machine.  For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel.  The ssh pro‐
                gram will be put in the background.  (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.)
      
      • ssh 行的末尾添加&lt;/dev/null(即ssh ... &lt;/dev/null)将解决问题并使ssh 的行为符合预期。

      • read 读取一个不太可能被随机程序使用的File Descriptor

           while IFS= read -r line <&3; do
               # Here read is reading from FD 3, to which 'ip_host.list' is redirected.
           done 3<ip_host.list
        

      【讨论】:

      • 嗨 Rany,非常感谢,它对我有用!我在 ssh 的行尾添加了“/null”,现在一切正常!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多