호스트 이름 목록을 출력하는 명령을 작성했습니다. 예를 들면 다음과 같습니다.
clab148node11
clab148node12
clab148node15
clab148node16
이제 핑에 응답하지 않는 노드를 제거하고 싶습니다. 이제 다음과 같은 것이 있습니다.
for node in $nodes
do
result=$(ping -c 1 $node; echo $?)
done
$result
이제 0이 아닌 노드를 어떻게 삭제하나요 ?
답변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