Bagaimana saya bisa melakukan ping ke alamat tertentu dan ketika ditemukan, berhentilah melakukan ping.
Saya ingin menggunakannya dalam skrip bash, jadi ketika host memulai, skrip terus melakukan ping dan sejak host tersedia, skrip berlanjut ...
Bagaimana saya bisa melakukan ping ke alamat tertentu dan ketika ditemukan, berhentilah melakukan ping.
Saya ingin menggunakannya dalam skrip bash, jadi ketika host memulai, skrip terus melakukan ping dan sejak host tersedia, skrip berlanjut ...
Jawaban:
Penyederhanaan lebih lanjut dari jawaban Martynas:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
perhatikan bahwa ping itu sendiri digunakan sebagai tes loop; begitu berhasil, loop berakhir. Badan loop kosong, dengan perintah " :
" nol digunakan untuk mencegah kesalahan sintaks.
Pembaruan: Saya memikirkan cara untuk membuat Control-C keluar dari loop ping dengan bersih. Ini akan menjalankan loop di latar belakang, menjebak sinyal interrupt (Control-C), dan membunuh loop latar belakang jika terjadi:
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"
Agak berputar-putar, tetapi jika Anda ingin loop dapat dibatalkan itu harus melakukan trik.
ping
akan menunggu 10 detik sebelum menyerah pada pingnya. Jika Anda ingin mengurangi itu menjadi 1 detik, Anda dapat menggunakannya -w1
.
-W1
kill %1
membunuhnya.
Anda dapat melakukan loop, mengirim satu ping dan tergantung pada status break loop, misalnya (bash):
while true; do ping -c1 www.google.com > /dev/null && break; done
Menempatkan ini di suatu tempat di skrip Anda akan diblokir, sampai www.google.com
dapat diputuskan.
while true
dan break
merupakan solusi bersih, IMO.
while true; do sleep 5; ping ...
Saya tahu pertanyaannya sudah lama ... dan secara khusus menanyakan ping
, tetapi saya ingin membagikan solusi saya.
Saya menggunakan ini ketika me-reboot host untuk mengetahui kapan saya bisa SSH kembali ke mereka lagi. (Karena ping
akan merespons selama beberapa detik sebelum sshd
dimulai.)
until nc -vzw 2 $host 22; do sleep 2; done
Ping host target sekali. Periksa apakah ping berhasil (nilai balik ping adalah nol). Jika host tidak hidup, ping lagi.
Kode berikut dapat disimpan sebagai file dan dipanggil dengan nama host sebagai argumen, atau dilucuti dari baris pertama dan terakhir dan digunakan sebagai fungsi dalam skrip yang ada (waitForHost hostname).
Kode tidak mengevaluasi penyebab kegagalan jika ping tidak menghasilkan respons, sehingga berulang selamanya jika host tidak ada. Manual BSD saya mencantumkan arti dari masing-masing nilai kembali, sedangkan yang linux tidak, jadi saya kira ini mungkin tidak portabel, itu sebabnya saya meninggalkannya.
#!/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
Silakan lihat opsi yang baik di stackoverflow . Berikut ini contoh dalam bash, Anda harus mengulang kode berikut hingga mengembalikan hasil ping yang berhasil.
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
salah satu loop di atas juga dapat digunakan dengan fping daripada ping yang, IMO, lebih cocok untuk digunakan dalam skrip daripada ping itu sendiri. Lihat fping (1) untuk detailnya.
while ! fping -q $HOSTNAMES ; do :; done
juga berguna untuk menguji apakah mesin sudah bangun sebelum melakukan sesuatu pada mereka. Contoh sederhana:
untuk h di HOST1 HOST2 HOST3; melakukan jika fping -q $ h; kemudian echo -n "$ h:" ssh $ h "uname -a" fi Selesai
Ini akan mencoba beberapa kali.
t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r
Alih-alih menggema $r
, Anda dapat mengujinya dan bertindak sesuai nilainya:
if ((r)); then echo 'Failed to contact host'; else echo 'Continuing with script'; fi
Untuk menangani SIGINT dengan baik pada BSD ping.
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"
sebagai fungsi
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
}
Saya telah menggunakan fungsi berikut. Saya suka karena saya bisa mengatakan itu untuk berhenti mencoba setelah beberapa saat:
#!/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
}
Dapat digunakan seperti ini untuk meluncurkan sesuatu:
# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
firefox &
fi
Secara umum saya ingin menunggu database atau server lain muncul, tetapi saya tidak ingin menunggu terlalu lama. Kode berikut menunggu selama 10 detik, kemudian menetapkan kode keluar jika server tidak muncul dalam batas waktu.
Jika server muncul sebelum batas waktu, loop akan dihubung pendek sehingga bit kode berikutnya dapat berjalan.
for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${HOST} &>/dev/null && break ; done