it-swarm-vi.tech

Làm thế nào để ping trong linux cho đến khi Host được biết đến?

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 tập lệnh bash, vì vậy khi Máy chủ khởi động, tập lệnh tiếp tục bị ping và kể từ thời điểm Máy chủ khả dụng, tập lệnh tiếp tục ...

50
Sander Versluys

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. 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.

87
Gordon Davisson

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 là pingable.

25
Martynas Saint

Tôi biết câu hỏi đã cũ ... và đặc biệt hỏi về 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 được bắt đầu.)

until nc -vzw 2 $Host 22; do sleep 2; done
22
Aaron Copley

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 Host không còn hoạt động, hãy 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
11
Jan Jungnickel
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ]; 
   do ping -q -c 1 Host &> /dev/null; UNREACHEABLE=$?; sleep 1;
done

Bạn có thể xóa chế độ ngủ 1, chỉ ở đây để ngăn chặn mọi sự cố ngập lụt trong trường hợp Máy chủ có thể truy cập được nhưng ping sẽ không thoát với mã 0.

9
radius

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
 [.__.]
4
Francois Wolmarans

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 đó [.__.] echo -n "$ h:" [.__.] ssh $ h "uname -a" [.___
3
cas

Để 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
}
1
Luke Exton

Đ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

Đối với người dùng macOS, ping có tùy chọn -o cụ thể cho việc này:

-o      Exit successfully after receiving one reply packet.

Vì vậy, lệnh rất đơn giản:

ping -o www.google.com

Nó trả về 0 khi Máy chủ đã được ping thành công một lần.

1
Melebius

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 đợi quá dài. Đ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
0
johntellsall

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
0
oneself

Một cải tiến hơn nữa cho câu trả lời của Gordon Davisson:

until $(ping -c1 www.google.com &>/dev/null); do :; done

với '$ ()' xung quanh, một lớp con được bắt đầu và do đó bạn có thể sử dụng Control-C để chấm dứt vòng lặp trong trường hợp Máy chủ không khả dụng.

0
Shawn