【问题标题】:How do I run many SSH remote commands, on multiple machines, in batch?如何在多台机器上批量运行许多 SSH 远程命令?
【发布时间】:2013-12-06 18:06:23
【问题描述】:

我使用 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

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

【问题讨论】:

  • 不能在后台运行吗??并通过 <your command> 2>/dev/null 忽略错误
  • 您是否尝试过在调试模式(即详细模式)下执行 ssh?

标签: shell for-loop ssh timeout


【解决方案1】:

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

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

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

这是一个使用 GNU 并行 的解决方案,最多同时运行 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> 将通过拆分<arguments> 列表并行执行<command> <argument> 多次。 <argument> 的占位符是 {}

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

【讨论】:

    【解决方案2】:

    连接超时适用于您已经建立连接并且如果连接在几秒钟内保持空闲时间,那么它将断开连接(也就是说,如果您还没有激活阻止连接的 KEEP_ALIVE ssh 参数永远闲着)。

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

    【讨论】:

    • 此答案与 SSH 文档相矛盾(此外,即使操作系统不允许您正确缩短套接字的超时时间,您仍然可以运行自己的计时器并在任何时间后放弃尝试)。这是ssh_config(5)手册页中关于ConnectTimeout选项的相关部分:“指定连接到SSH服务器时使用的超时(以秒为单位),而不是使用默认的系统TCP超时。该值仅在目标关闭或确实无法访问时使用,而不是在它拒绝连接时使用。”
    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2014-04-07
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 2022-08-06
    • 1970-01-01
    相关资源
    最近更新 更多