xargs sh -c 'ssh ...' 任何连接超时时停止执行

xargs sh -c 'ssh ...' stopping execution when any connection times out

我在 bash 中写了一个小衬垫来在我的服务器上吐出 openssl 版本 (checking if I'm protected against this most recent openssl vulnerability),但是如果 SSH 无法连接并超时,它会停止其余的脚本从执行..我知道足够 bash 绕过,但我不太确定这里需要做什么来强制它继续,也许捕获 SIGTERM 并从我离开的地方继续?我确定有更简单的方法..

命令如下:

cat servers.txt | \
  xargs -I {} sh -c "echo {} && ssh -o ConnectTimeout=3 myusername@{} openssl version"

其中 servers.txt 只是一个 IP 地址的大列表,每行一个

来自 xargs 手册页:

The xargs utility exits immediately (without processing any further input) if a command line cannot be assembled, utility cannot be invoked, an invocation of utility is terminated by a signal, or an invocation of utility exits with a value of 255.

大概您的失败是以 255 状态退出。


就我个人而言,我不会为这个 xargs 而烦恼;你没有做任何事情(比如并行化,或者在命令行上放置多个主机名)它特别适合。

while read -r name <&3; do
  echo "$name"; ssh -o ConnectTimeout=3 username@"$name" "openssl version" ||:
done 3<servers.txt

这使用文件描述符 3 读取 servers.txt 文件,因此 stdin 保留为默认值。


顺便说一句,如果我要编写您的代码来使用 xargs,我会这样做:

xargs sh -c 'for host; do ssh -o ConnectTimeout=3 myusername@"$host" "openssl version" </dev/null' _ <servers.txt

这样您就可以让 xargs 将 主机列表 传递给每个 shell 调用,而不是每个主机一个 shell。

基本上你需要NOHUP

"nohup command-name &" 或

"nohup /path/to/command-name arg1 arg2 &"

您也正在序列化到 servers.txt,我想您可能会喜欢 在内容上 运行 一个 foreach(),运行 在后台对每个进行调用。

然而,这会产生如何获得结果的次要问题? (提示:追加到固定名称 results.log)

使用专为此类工作而设计的 GNU Parallel:

parallel -j0 --retries 3 --slf servers --nonall --timeout 1000% --tag openssl version

您需要在 'servers' 中的行前面添加 'myusername@' 或在 ~/.ssh/config.

中使用 'User myusername'