特定のアドレスに対してpingを実行し、見つかったらpingを停止する方法を教えてください。
私はそれをbashスクリプトで使用したいので、ホストが起動している間、スクリプトはpingを続け、ホストが利用可能になった瞬間から、スクリプトは続行します...
マーティナスの答えをさらに簡略化:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
ping自体がループテストとして使用されることに注意してください。成功するとすぐにループが終了します。ループ本体は空で、ヌルコマンド ":
"は、構文エラーを防ぐために使用されます。
更新:Control-Cがpingループを完全に終了する方法を考えました。これにより、バックグラウンドでループが実行され、割り込み(Control-C)信号がトラップされ、バックグラウンドループが発生した場合はそれが強制終了されます。
ping_cancelled=false # Keep track of whether the loop was cancelled, or succeeded
until ping -c1 "$1" >/dev/null 2>&1; do :; done & # The "&" backgrounds it
trap "kill $!; ping_cancelled=true" SIGINT
wait $! # Wait for the loop to exit, one way or another
trap - SIGINT # Remove the trap, now we're done with it
echo "Done pinging, cancelled=$ping_cancelled"
それは少し遠回りですが、ループをキャンセル可能にしたい場合は、それでうまくいくはずです。
ループを実行して1つのpingを送信し、ステータスに応じてループを中断することができます(例:(bash))。
while true; do ping -c1 www.google.com > /dev/null && break; done
これをスクリプトのどこかに置くと、www.google.com
はping可能です。
私は質問が古いことを知っています...そして特にping
について尋ねますが、私の解決策を共有したいと思いました。
ホストを再起動するときにこれを使用して、いつSSHで再びホストに戻ることができるかを確認します。 (ping
が開始される前にsshd
が数秒間応答するため。)
until nc -vzw 2 $Host 22; do sleep 2; done
ターゲットホストを1回pingします。 pingが成功したかどうかを確認します(pingの戻り値はゼロです)。ホストが稼働していない場合は、もう一度pingを実行します。
次のコードは、ファイルとして保存してホスト名を引数として呼び出すか、最初と最後の行を削除して、既存のスクリプト内で関数として使用できます(waitForHostホスト名)。
Pingの結果が応答でない場合、コードは失敗の原因を評価しないため、ホストが存在しない場合は永久にループします。私のBSDマンページには、各戻り値の意味が記載されていますが、Linuxには記載されていないため、これは移植性がない可能性があるため、省略しました。
#!/bin/bash
PING=`which ping`
function waitForHost
{
if [ -n "$1" ];
then
waitForHost1 $1;
else
echo "waitForHost: Hostname argument expected"
fi
}
function waitForHost1
{
reachable=0;
while [ $reachable -eq 0 ];
do
$PING -q -c 1 $1
if [ "$?" -eq 0 ];
then
reachable=1
fi
done
sleep 5
}
waitForHost $1
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ];
do ping -q -c 1 Host &> /dev/null; UNREACHEABLE=$?; sleep 1;
done
スリープ1を削除できます。これは、ホストに到達できるがpingがコード0で終了しない場合にフラッディングの問題を防ぐためだけにあります。
stackoverflow で適切なオプションを参照してください。以下はbashのサンプルです。pingの結果が正常に返されるまで、次のコードをループする必要があります。
ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
echo "192.168.1.1 is up";
else
echo "ip is down";
fi
上記のループは、pingではなくfpingでも使用できます。IMOは、ping自体よりもスクリプトでの使用に適しています。詳細は fping(1) を参照してください。
while ! fping -q $HOSTNAMES ; do :; done
マシンで何かをする前にマシンが稼働しているかどうかをテストするのにも役立ちます。簡単な例:
ホスト1、ホスト2、ホスト3のhの場合。 do if fping -q $ h;次に、 echo -n "$ h:" ssh $ h "uname -a" fi done
BSD pingでSIGINTを適切に処理するため。
Host=google.com NO=1; while [ $NO -ne 0 ]; do ping -W1 -c1 $Host &>/dev/null; NO=$?;echo "$(date) ($Host) $NO" ; done; echo "$(date) ($Host) reachable"
関数として
ping_until(){
local NO=1
while [ $NO -ne 0 ]; do
ping -W1 -c1 $1 &>/dev/null; NO=$?
# Optionally block ICMP flooding
# sleep 1
echo "$(date) ($1) ($NO)"
done
}
これは、指定された回数試行します。
t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r
$r
をエコーする代わりに、それをテストし、その値に従って動作することができます。
if ((r)); then echo 'Failed to contact Host'; else echo 'Continuing with script'; fi
MacOSユーザーの場合、ping
には特に-o
オプションがあります。
-o Exit successfully after receiving one reply packet.
したがって、コマンドは簡単です:
ping -o www.google.com
ホストが一度pingに成功すると、0を返します。
一般的に、データベースや他のサーバーが起動するのを待ちたいが、too長く待ちたくない。次のコードは10秒間待機し、サーバーが制限時間内に表示されなかった場合に終了コードを設定します。
サーバーが制限時間より前に表示されると、ループが短絡され、次のコードが実行されます。
for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${Host} &>/dev/null && break ; done
以下の機能を利用しています。しばらくするとやめるように言うことができるので、気に入っています。
#!/usr/bin/env bash
function networkup {
# Initialize number of attempts
reachable=$1
while [ $reachable -ne 0 ]; do
# Ping supplied Host
ping -q -c 1 -W 1 "$2" > /dev/null 2>&1
# Check return code
if [ $? -eq 0 ]; then
# Success, we can exit with the right return code
echo 0
return
fi
# Network down, decrement counter and try again
let reachable-=1
# Sleep for one second
sleep 1
done
# Network down, number of attempts exhausted, quiting
echo 1
}
このように使用して何かを起動できます。
# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
firefox &
fi
ゴードン・デイヴィッソンの答えのさらなる強化:
until $(ping -c1 www.google.com &>/dev/null); do :; done
周囲の '$()'でサブシェルが開始されるため、ホストが使用できなくなった場合にControl-Cを使用してループを終了できます。