
複数のサーバーにリモートで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
ここでは、基本的なプログラムフローにいくつかの問題があります。ここに設定がある場合、実際に追跡されるいくつかの点があります。
- この確認中にリスト内のホストでまだプロセスが実行されている場合は、それを記録して再確認する必要があります。
- まだプロセスがあるホストの数がゼロの場合は終了する必要があります。
したがって、このスクリプトには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にリダイレクトされます。pgrep
pdsh
唯一の出力はgrep pattern
パイプから来ます。grep -q pattern
ミュートしたい場合でもこの機能を使用してください。