如何在多台计算机上批量运行多个SSH远程命令?

时间:2013-11-22 01:05:25

标签: shell for-loop ssh timeout

我使用SSH在for循环中的多个远程计算机上运行某些命令。它为IP地址列表执行相同的命令。某些IP地址可能无法访问,因此我使用了ConnectTimeout选项。

但是,我的脚本没有按照我想要的方式工作。实际上它停留在第一个无法访问的IP而不是放弃并尝试列表中的下一个IP地址。

以下是我的脚本的相关部分:

for ip in ${IP} ; do
    ssh  -o BatchMode=yes \
         -o StrictHostKeyChecking=no \
         -o ConnectTimeout=10 \
         -l ${USERNAME} \
         ${SCRIPT_HOST} \
         "${COMMAND} -i $ip || echo timeout" \
         >> ./myscript.out
done

它对于可访问的IP工作正常,但如果某个特定IP已关闭,它会等待一段时间(远超过10秒,可能是35-40秒)并向我的终端显示错误消息:

ERROR connecting : Connection timed out

所以我想知道我没有正确使用哪个选项。

2 个答案:

答案 0 :(得分:15)

您对ConnectTimeout的使用是正确的,因此不清楚为什么它只会在30秒或更长时间后超时。

以下是我将如何更改脚本以完全避免超时问题:

  • 使用GNU parallel同时连接到多个目标主机。
  • 使用SSH -f选项在后台处理它。

以下是 GNU parallel 的解决方案,同时运行最多50个连接:

parallel --gnu --bg --jobs 50 \
ssh -o BatchMode=yes \
    -o StrictHostKeyChecking=no \
    -o ConnectTimeout=10 \
    -l ${USERNAME} \
    {} \
    "${COMMAND} -i {} || echo timeout" \
::: ${IP}

parallel <command> ::: <arguments>将通过拆分<command> <argument>列表多次并行执行<arguments><argument>的占位符为{}

使用parallel --jobs n限制并行连接数。

答案 1 :(得分:1)

连接超时是指您已经建立连接并且连接在几秒钟内保持空闲状态的时间,然后它将断开连接(即如果您还没有激活阻止连接的KEEP_ALIVE ssh参数永远闲着)。

在你超时之前需要30多秒的原因是因为它是TCP协议内部计时器,试图连接这段时间并返回他无法连接到sftp服务器的错误消息。它不是来自ssh。