ฉันจะส่ง Ping ไปยังที่อยู่ที่แน่นอนได้อย่างไรและเมื่อพบให้หยุดส่ง Ping
ฉันต้องการใช้มันในสคริปต์ทุบตีดังนั้นเมื่อโฮสต์เริ่มต้นสคริปต์จะยังคงกระตุกและจากช่วงเวลาที่โฮสต์พร้อมใช้งานสคริปต์จะดำเนินต่อไป ...
ฉันจะส่ง Ping ไปยังที่อยู่ที่แน่นอนได้อย่างไรและเมื่อพบให้หยุดส่ง Ping
ฉันต้องการใช้มันในสคริปต์ทุบตีดังนั้นเมื่อโฮสต์เริ่มต้นสคริปต์จะยังคงกระตุกและจากช่วงเวลาที่โฮสต์พร้อมใช้งานสคริปต์จะดำเนินต่อไป ...
คำตอบ:
ความเรียบง่ายเพิ่มเติมของคำตอบของ Martynas:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
โปรดทราบว่าการ ping นั้นใช้เป็นการทดสอบลูป ทันทีที่มันประสบความสำเร็จลูปจะสิ้นสุดลง วนรอบร่างกายว่างเปล่าโดยใช้คำสั่ง null " :
" เพื่อป้องกันข้อผิดพลาดทางไวยากรณ์
อัปเดต: ฉันคิดถึงวิธีที่จะทำให้ Control-C ออกจากลูปปิงอย่างหมดจด สิ่งนี้จะเรียกใช้ลูปในพื้นหลังดักสัญญาณ interrupt (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"
มันค่อนข้างจะเป็นวงจร แต่ถ้าคุณต้องการยกเลิกการวนซ้ำ
ping
จะรอ 10 วินาทีก่อนที่จะยอมแพ้ ping หากคุณต้องการที่จะลดที่ 1 -w1
วินาทีคุณสามารถใช้
-W1
kill %1
ฆ่ามัน
คุณสามารถทำลูปส่ง ping หนึ่งอันและขึ้นอยู่กับการแบ่งสถานะของลูปตัวอย่างเช่น (bash):
while true; do ping -c1 www.google.com > /dev/null && break; done
การวางตำแหน่งนี้ไว้ในสคริปต์ของคุณจะบล็อกจนกว่าwww.google.com
จะสามารถทำได้
while true
และbreak
เป็นวิธีการแก้ทำความสะอาด, IMO
while true; do sleep 5; ping ...
ฉันรู้ว่าคำถามนั้นเก่าแล้วและถามโดยเฉพาะเกี่ยวกับเรื่องping
นี้ แต่ฉันต้องการแบ่งปันวิธีแก้ปัญหาของฉัน
ฉันใช้สิ่งนี้เมื่อรีบูตเครื่องโฮสต์เพื่อทราบว่าเมื่อใดที่ฉันจะสามารถ SSH กลับเข้าไปในพวกเขาอีกครั้ง (เนื่องจากping
จะตอบสนองเป็นเวลาหลายวินาทีก่อนที่sshd
จะเริ่ม)
until nc -vzw 2 $host 22; do sleep 2; done
Ping โฮสต์เป้าหมายหนึ่งครั้ง ตรวจสอบว่าการ ping สำเร็จ (ค่าส่งคืนของ ping เป็นศูนย์) หากโฮสต์ไม่ได้อยู่ให้ปิงอีกครั้ง
รหัสต่อไปนี้สามารถบันทึกเป็นไฟล์และเรียกใช้ด้วยชื่อโฮสต์เป็นอาร์กิวเมนต์หรือถอดจากบรรทัดแรกและบรรทัดสุดท้ายและใช้เป็นฟังก์ชันภายในสคริปต์ที่มีอยู่ (ชื่อโฮสต์ waitForHost)
รหัสไม่ได้ประเมินสาเหตุของความล้มเหลวหากการ ping ไม่ส่งผลให้เกิดการตอบสนองดังนั้นการวนซ้ำตลอดไปหากไม่มีโฮสต์อยู่ BSD manpage ของฉันแสดงความหมายของแต่ละค่าที่ส่งคืนในขณะที่ 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
คุณสามารถลบ sleep 1 ได้ที่นี่เพื่อป้องกันปัญหาน้ำท่วมในกรณีที่โฮสต์สามารถเข้าถึงได้ แต่ ping จะไม่ออกจากด้วยรหัส 0
การวนรอบด้านบนใด ๆ ยังสามารถใช้กับ fping แทน ping ซึ่ง IMO เหมาะสำหรับการใช้ในสคริปต์มากกว่า ping เอง ดูfping (1)สำหรับรายละเอียด
while ! fping -q $HOSTNAMES ; do :; done
ยังมีประโยชน์สำหรับการทดสอบว่าเครื่องจักรทำงานก่อนที่จะทำอะไรกับมัน ตัวอย่างง่ายๆ:
สำหรับ h ใน HOST1 HOST2 HOST3; ทำ ถ้า fping -q $ h; แล้วก็ echo -n "$ h:" ssh $ h "uname -a" Fi เสร็จแล้ว
วิธีนี้จะลองตามจำนวนครั้งที่กำหนด
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
เพื่อจัดการ SIGINT บน 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"
เป็นฟังก์ชั่น
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
}
ฉันใช้ฟังก์ชั่นต่อไปนี้แล้ว ฉันชอบเพราะฉันสามารถบอกได้ว่าให้หยุดพยายามอีกสักครู่:
#!/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
โดยทั่วไปฉันต้องการรอให้ฐานข้อมูลหรือเซิร์ฟเวอร์อื่น ๆ ของฉันมา แต่ฉันไม่ต้องการรอนานเกินไป รหัสต่อไปนี้รอเป็นเวลา 10 วินาทีจากนั้นตั้งรหัสออกหากเซิร์ฟเวอร์ไม่ปรากฏภายในเวลาที่กำหนด
หากเซิร์ฟเวอร์ปรากฏก่อนกำหนดเวลาลูปจะถูกลัดวงจรเพื่อให้สามารถเรียกใช้โค้ดถัดไปได้
for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${HOST} &>/dev/null && break ; done
การปรับปรุงเพิ่มเติมสำหรับคำตอบของ Gordon Davisson:
until $(ping -c1 www.google.com &>/dev/null); do :; done
ด้วยการล้อมรอบ '$ ()' จะมีการเริ่มต้น subshell ดังนั้นคุณสามารถใช้ Control-C เพื่อยุติการวนซ้ำในกรณีที่โฮสต์ไม่สามารถใช้งานได้