Làm thế nào tôi có thể ping một địa chỉ nhất định và khi tìm thấy, ngừng ping.
Tôi muốn sử dụng nó trong một tập lệnh bash, vì vậy khi máy chủ khởi động, tập lệnh tiếp tục ping và từ thời điểm máy chủ có sẵn, tập lệnh tiếp tục ...
Làm thế nào tôi có thể ping một địa chỉ nhất định và khi tìm thấy, ngừng ping.
Tôi muốn sử dụng nó trong một tập lệnh bash, vì vậy khi máy chủ khởi động, tập lệnh tiếp tục ping và từ thời điểm máy chủ có sẵn, tập lệnh tiếp tục ...
Câu trả lời:
Một đơn giản hóa hơn nữa câu trả lời của Martynas:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
lưu ý rằng bản thân ping được sử dụng làm bài kiểm tra vòng lặp; Ngay khi nó thành công, vòng lặp kết thúc. Phần thân vòng lặp trống, với lệnh null " :
" được sử dụng để ngăn lỗi cú pháp.
Cập nhật: Tôi đã nghĩ ra một cách để làm cho Control-C thoát khỏi vòng ping một cách sạch sẽ. Điều này sẽ chạy vòng lặp trong nền, bẫy tín hiệu ngắt (Control-C) và giết vòng lặp nền nếu xảy ra:
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"
Nó hơi phức tạp, nhưng nếu bạn muốn vòng lặp có thể hủy được thì nên thực hiện thủ thuật.
ping
sẽ đợi 10 giây trước khi từ bỏ ping của nó. Nếu bạn muốn giảm xuống còn 1 giây, bạn có thể sử dụng -w1
.
-W1
kill %1
để giết nó.
Bạn có thể thực hiện một vòng lặp, gửi một ping và tùy thuộc vào trạng thái phá vỡ vòng lặp, ví dụ (bash):
while true; do ping -c1 www.google.com > /dev/null && break; done
Đặt cái này ở đâu đó trong tập lệnh của bạn sẽ chặn, cho đến khi www.google.com
có thể ping được.
while true
và break
là giải pháp sạch hơn, IMO.
while true; do sleep 5; ping ...
Tôi biết câu hỏi đã cũ ... và đặc biệt hỏi về vấn đề này ping
, nhưng tôi muốn chia sẻ giải pháp của mình.
Tôi sử dụng điều này khi khởi động lại máy chủ để biết khi nào tôi có thể SSH lại vào chúng. (Vì ping
sẽ trả lời trong vài giây trước khi sshd
bắt đầu.)
until nc -vzw 2 $host 22; do sleep 2; done
Ping máy chủ đích một lần. Kiểm tra xem ping có thành công không (giá trị trả về của ping bằng 0). Nếu máy chủ không còn sống, ping lại.
Mã sau đây có thể được lưu dưới dạng tệp và được gọi với tên máy chủ làm đối số hoặc tước dòng đầu tiên và dòng cuối cùng và được sử dụng làm hàm trong tập lệnh hiện có (tên máy chủ WaitForhost).
Mã không đánh giá nguyên nhân thất bại nếu ping không dẫn đến phản hồi, do đó lặp lại mãi mãi nếu máy chủ không tồn tại. Trang chủ BSD của tôi liệt kê ý nghĩa của từng giá trị trả về, trong khi phiên bản linux thì không, vì vậy tôi đoán đây có thể không phải là di động, đó là lý do tại sao tôi bỏ nó.
#!/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
Xin vui lòng xem các tùy chọn tốt tại stackoverflow . Đây là một mẫu trong bash, bạn sẽ phải lặp qua đoạn mã sau cho đến khi nó trả về kết quả ping thành công.
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
bất kỳ vòng lặp nào ở trên cũng có thể được sử dụng với fping thay vì ping, IMO, phù hợp hơn để sử dụng trong các tập lệnh hơn là chính ping. Xem fping (1) để biết chi tiết.
while ! fping -q $HOSTNAMES ; do :; done
cũng hữu ích để kiểm tra nếu máy hoạt động trước khi làm gì đó với chúng. Một ví dụ đơn giản:
cho h trong HOST1 HOST2 HOST3; làm nếu fping -q $ h; sau đó tiếng vang -n "$ h:" ssh $ h "uname -a" fi làm xong
Điều này sẽ thử một số lần nhất định.
t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r
Thay vì lặp lại $r
, bạn có thể kiểm tra nó và hành động theo giá trị của nó:
if ((r)); then echo 'Failed to contact host'; else echo 'Continuing with script'; fi
Để xử lý độc đáo SIGINT trên 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"
như một chức năng
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ôi đã sử dụng chức năng sau đây. Tôi thích nó bởi vì tôi có thể bảo nó ngừng cố gắng sau một thời gian:
#!/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
}
Nó có thể được sử dụng như thế này để khởi chạy một cái gì đó:
# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
firefox &
fi
Nói chung, tôi muốn đợi cơ sở dữ liệu của mình hoặc máy chủ khác xuất hiện, nhưng tôi không muốn chờ quá lâu. Đoạn mã sau đợi trong 10 giây, sau đó đặt mã thoát nếu máy chủ không xuất hiện trong thời gian giới hạn.
Nếu máy chủ xuất hiện trước thời hạn, vòng lặp sẽ bị ngắn mạch để bit mã tiếp theo có thể chạy.
for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${HOST} &>/dev/null && break ; done