Bashスクリプトは、複数のサーバーのプロセスが完了するのを待ちます。

Bashスクリプトは、複数のサーバーのプロセスが完了するのを待ちます。

複数のサーバーにリモートでSSHを介してそのサーバーで実行されているプロセスがあることを確認し、そのプロセスが完了するのを待ちたいと思います。以下のコードを書いて「continue」ステートメントを追加したので、ファイル(ip.txt)の最初のIPだけを確認します。このコードを修正する必要があります。

  while read IP
  do
    ssh ubuntu@$IP "pgrep -f pattern"
    if [ $? -eq 0 ]; then
       echo "Process is running" 
       sleep 10
       continue
    else
       echo "Process is not running"
    fi
  done < ip.txt

答え1

IPリストを最初にソートしてから繰り返すことをお勧めします。

mapfile ipaddresses < ip.txt
canary=alive
while [[ "alive" == "$canary" ]]; do
  canary=dead
  for ip in ${ipaddresses[@]}; do
    if ssh ubuntu@$ip "pgrep -f pattern"; then
      echo "Process is running on $ip"
      canary=alive
      sleep 10
      continue
    else
      echo "Process not running on $ip"
    fi
  done
done

それでも4未満のバージョンで停止している場合は、bashコマンドmapfileを次のように置き換えます。

read -r ipaddresses <<< "$( cat ip.txt )"

答え2

ここでは、基本的なプログラムフローにいくつかの問題があります。ここに設定がある場合、実際に追跡されるいくつかの点があります。

  1. この確認中にリスト内のホストでまだプロセスが実行されている場合は、それを記録して再確認する必要があります。
  2. まだプロセスがあるホストの数がゼロの場合は終了する必要があります。

したがって、このスクリプトには2つのループを使用します。また、continueここでは必要ありません。これにより、毎回最初のホストが繰り返されることがあります。

psget私は主にssh終了コードをチェックするのではなく、返されたPIDの数をテストし、少し異なる構文を使用して何か別の操作を実行しました。以下は、あなたが望むものに合ったように見える例です。

#!/bin/bash
set -eu

# get number of IPs from lines in file
NUM_IPS=$( cat ip.txt | wc -l )
echo "checking ${NUM_IPS} hosts..."

# Set number of running hosts to the max.  While arbitrary, it will 
# update to the correct number before reporting, and if it is 0 the
# while loop will exit immediately.
IPS_STILL_RUNNING=${NUM_IPS}

while [ "${IPS_STILL_RUNNING}" -gt "0" ]
do
    RUNNING_NOW=0
    for IP in $( cat ip.txt )
    do
        PROC_NUM=$( ssh ${IP} -- pgrep -f pattern | wc -l )
        if [ "${PROC_NUM}" -gt "0" ]; then
            echo "  ${IP}: still running"
            RUNNING_NOW=$(( RUNNING_NOW + 1 ))
        else
            echo "  ${IP}: not running"
        fi
    done
    echo "still running on $RUNNING_NOW hosts"
    IPS_STILL_RUNNING=${RUNNING_NOW}
    sleep 10
done

答え3

複数のホストを並列に接続するには、ssh(Parallel Distributed Shell)などのプログラムを使用してください。pdsh

たとえば、ip.txtホスト名の代わりにIPアドレスを含める場合、またはホスト名とIPアドレスを混在させる場合:

hosts="$(awk '{l = l","$0}; END {sub(/^,/,"",l); print l}' ip.txt)"
while pdsh -l ubuntu -w "$hosts" 'pgrep -f pattern' 2>/dev/null | 
        grep pattern ; do
  sleep 10
done

awkこれは、転送するIPアドレスのカンマ区切りリストを作成するために使用されますssh

ip.txtファイルに以下が含まれている場合ただIPアドレスの代わりにホスト名が簡単です。

while pdsh -l ubuntu -F ./ip.txt -a 'pgrep -f pattern' 2>/dev/null | 
        grep pattern ; do
  sleep 10
done

ip.txtどちらも1行に1つのIPアドレスまたはホスト名があるとします。

while次までループを実行してください。まったくホスト出力どのパターンに一致する出力です。pdshコマンドが終了コード1を返したときに端末にエラーメッセージを送信しないように、コマンドのstderrは/ dev / nullにリダイレクトされます。pgreppdsh

唯一の出力はgrep patternパイプから来ます。grep -q patternミュートしたい場合でもこの機能を使用してください。

関連情報