ホスト名リストを出力するコマンドを作成しました。たとえば、次のようになります。
clab148node11
clab148node12
clab148node15
clab148node16
ここで、pingに応答しないノードを削除したいと思います。今、次のようなものがあります。
for node in $nodes
do
result=$(ping -c 1 $node; echo $?)
done
$result
今、ゼロ以外のノードをどのように削除しますか?
答え1
私は新しいリストを作成し、古いリストを新しいリストに置き換えることを好みます。
nodes="127.0.0.1 1.2.3.4 1.2.3.4 "
nodes_out=
for node in $nodes
do
ping -c 1 $node >/dev/null 2>&1 && nodes_out+=$node
done
nodes=$nodes_out
答え2
@manatworkが言ったように、有効なノードを使用して新しいリストを作成する方が簡単で安全に見えます。
ただし、「$ nodes」はforループの最初の繰り返しの前に評価されるため、同じループ中にこれを変更できます。
$ nodes="127.0.0.1 1.2.3.4 1.2.3.4 "
$ for node in $nodes; do
result=$(ping -c 1 $node >/dev/null 2>/dev/null; echo $?);
if [ "$result" -ne 0 ];
then nodes=$(echo $nodes | sed -e "s/ *$node */ /");
fi;
echo result=$result node=$node nodes=$nodes ;
done ;
注:私のsedは、リストの位置に応じて、すべての場合に交換または動作します[space]$node[space]
(中間、最初、または最後の要素にある場合は、前後にスペースがあるかどうか)。一度に1つのアイテムのみを置き換えることはできますが、サフィックスを追加してすべてのアイテムを一度に削除できます。$node[space]
[space]$node
$node
$nodes
/g
この出力は次のようになります。
result=0 node=127.0.0.1 nodes=127.0.0.1 1.2.3.4 1.2.3.4
result=1 node=1.2.3.4 nodes=127.0.0.1 1.2.3.4
result=1 node=1.2.3.4 nodes=127.0.0.1
答え3
別のオプションは、単にリバース grep を使用して、リスト内で一致するすべての項目を検索することです。いいえ一致するホスト:
for node in $nodes
do
if ! `ping -c 1 $node > /dev/null 2>&1`; then
nodes="`echo \"$nodes\" | grep -v \"$node\"`"
fi
done