每个ssh检查特定程序是否仍在运行,并行

时间:2014-11-25 01:18:54

标签: bash parallel-processing

我有几台运行程序的机器。每隔30秒左右,我想检查这些程序是否仍在运行。我使用以下命令来做到这一点。

ssh ${USER}@${HOSTS[i]} "bash -c 'if [[ -z \"\$(pgrep -u ${USER} program)\" ]]; then exit 1; else exit 0; fi'"

现在在> 100台机器上运行此操作需要很长时间,我想通过并行检查来加快速度。我知道'&'和'并行',但我不确定如何检索返回值(任务是否完成)。

1 个答案:

答案 0 :(得分:2)

以下内容允许所有连接在下一批中开始之前完成,因此可能等待超过30秒 - 但应该让您知道如何执行您正在寻找的内容:< / p>

hosts=( host1 host2 host3 )
user=someuser
script="script you want to run on each remote host"

last_time=$(( SECONDS - 30 ))
while (( ( SECONDS - last_time ) >= 30 )) || \
      sleep $(( 30 - (SECONDS - last_time) )); do
  last_time=$SECONDS
  declare -A pids=( )
  for host in "${hosts[@]}"; do
    ssh "${user}@${host}" "$script" & pids[$!]="$host"
  done
  for pid in "${!pids[@]}"; do
    wait "$pid" || {
      echo "Failure monitoring host ${pids[$pid]} at time $SECONDS" >&2
    }
  done
done

现在,更大的图片:不要这样做。

几乎每个操作系统都有一个流程监督框架。 Ubuntu有Upstart; Fedora和CentOS 7已经系统化; MacOS X已经推出; runit,daemontools和其他任何东西都可以安装在任何地方(而且非常非常容易使用 - 请查看http://smarden.org/runit/runscripts.html处的运行脚本示例。)

使用这些工具是监控流程的正确方法,并确保它在退出时重新启动:与此(非常高开销)解决方案不同,它们几乎没有任何开销,因为它们依赖于操作系统通知流程& #39;父进程退出时,而不是为进程进行轮询工作(只有在通过SSH连接,协商一对会话密钥,启动shell运行脚本等所有开销之后),等等。)

是的,这可能是一个小型的私人项目。尽管如此,你为自己制造了额外的复杂性(因而也就是额外的错误) - 如果你学会使用这些工具来做到这一点,你就会知道当你拥有这样的东西时如何做正确的事情。 不是一个小型私人项目。