ฉันจะบอกสคริปต์เพื่อรอให้กระบวนการเริ่มยอมรับการร้องขอบนพอร์ตได้อย่างไร


33

ฉันต้องการคำสั่งที่จะรอให้กระบวนการเริ่มยอมรับการร้องขอบนพอร์ตเฉพาะ

มีอะไรใน linux หรือเปล่า?

while (checkAlive -host localhost -port 13000 == false)
  do some waiting

...

คำตอบ:


52

การทดสอบที่ดีที่สุดเพื่อดูว่าเซิร์ฟเวอร์ยอมรับการเชื่อมต่อหรือไม่คือลองเชื่อมต่อจริงหรือไม่ ใช้ไคลเอนต์ปกติสำหรับโปรโตคอลใดก็ตามที่เซิร์ฟเวอร์ของคุณพูดและลองใช้คำสั่ง no-op

หากคุณต้องการมีน้ำหนักเบา TCP หรือ UDP ลูกค้าคุณสามารถขับรถเพียงจากเปลือกใช้netcat วิธีตั้งโปรแกรมการสนทนาขึ้นอยู่กับโปรโตคอล โพรโทคอลจำนวนมากมีเซิร์ฟเวอร์ปิดการเชื่อมต่อในอินพุตที่แน่นอนและ netcat จะออกจาก

while ! echo exit | nc localhost 13000; do sleep 10; done

คุณยังสามารถบอก netcat ให้ออกหลังจากสร้างการเชื่อมต่อ มันจะคืนค่า 1 หากไม่มีการเชื่อมต่อและ 0 หากมีดังนั้นเราจึงลบล้างเอาต์พุต มันอาจรองรับหนึ่งหรือทั้งสองคำสั่งต่อไปนี้ทั้งนี้ขึ้นอยู่กับ netcat รุ่นของคุณ

while ! nc -z localhost 13000 </dev/null; do sleep 10; done
while ! nc -q 1 localhost 13000 </dev/null; do sleep 10; done

อีกวิธีหนึ่งคือรอให้กระบวนการเซิร์ฟเวอร์เปิดซ็อกเก็ตการฟัง

while netstat -lnt | awk '$4 ~ /:13000$/ {exit 1}'; do sleep 10; done

หากคุณอยู่บน Mac OS, netstat จะใช้รูปแบบเอาต์พุตที่แตกต่างกันเล็กน้อยดังนั้นคุณจะต้องการอินสแตนซ์ต่อไปนี้:

while netstat -lnt | awk '$4 ~ /\.13000$/ {exit 1}'; do sleep 10; done

หรือคุณอาจต้องการกำหนดเป้าหมาย ID กระบวนการเฉพาะ:

while ! lsof -n -Fn -p $pid | grep -q '^n.*:13000$'; do sleep 10; done

ฉันไม่สามารถคิดวิธีที่จะตอบสนองต่อกระบวนการที่เริ่มฟังซ็อกเก็ต (ซึ่งจะหลีกเลี่ยงวิธีการโพล) ที่ใช้งานptraceไม่ได้


ฉันคิดว่า netcat เป็นคำตอบดังนั้นขอบคุณ เพื่อชี้แจงสิ่งที่ฉันพยายามทำคือเขียนสคริปต์เป็นส่วนหนึ่งของขั้นตอนการทำโหลดบาลานซ์ ฉันต้องเริ่มต้นกระบวนการรอให้ยอมรับคำขอบนพอร์ตแล้วปิดต้นฉบับ หากมีวิธีที่ดีกว่าในการทำสิ่งนี้แทนที่จะเขียนบทของตัวเอง
จะ

@ Will: นั่นเป็นคำถามที่แตกต่างกันมาก! ฉันเขียนคำตอบที่ต่างออกไป
Gilles 'หยุดชั่วร้าย'

1
ฉันชอบโซลูชัน netcat ด้วย ฉันมีสคริปต์ที่ใช้nc -w 2 </dev/null >/dev/null- หากการเชื่อมต่อใช้เวลานานกว่า 2 วินาทีมันจะหมดเวลาและล้มเหลว - ซึ่งเป็นประโยชน์สำหรับการใช้งานของฉัน
ephemient

FYI ฉันไม่สามารถรับ 'ในขณะที่ nc -q 1 localhost 13000 </ dev / null; นอนหลับ 10 ทำเพื่อทำงาน มันเพิ่งกลับมาทันที คนแรกทำงานได้ดีแม้ว่า ขอบคุณ!
Ellis Percival

@Flyte nc -q 1 localhost 13000 </dev/nullส่งคืนทันทีถ้าไม่มีเซิร์ฟเวอร์ที่รับฟัง แต่กลับมาพร้อมรหัสข้อผิดพลาดดังนั้น loop จะทำให้ sleep และลองอีกครั้งหลังจากนั้นสองสามวินาที
Gilles 'หยุดความชั่วร้าย'

17

หากคุณมี bash และ coreutils (เช่นหมดเวลานอน) แต่ไม่ใช่ nc / lsof / netstat คุณสามารถใช้โซลูชันนี้ซึ่งใช้ซ็อกเก็ต tcp magic bash:

while ! timeout 1 bash -c "echo > /dev/tcp/localhost/13000"; do sleep 10; done

ในการทำอย่างละเอียด Bash มีคุณสมบัติที่เป็นทางเลือกในการเชื่อมต่อกับซ็อกเก็ต TCP โดยใช้ "การเปลี่ยนเส้นทางเครือข่าย" - gnu.org/software/bash/manual/html_node/ ......
johntellsall

7

ตามตัวอย่างก่อนหน้านี้ด้วยbashเวทมนต์ tcp sockets ต่อไปนี้เป็นเวอร์ชั่นปรับปรุงที่รอการเชื่อมต่อในช่วงระยะเวลาที่ จำกัด

timeout 15 bash -c 'until echo > /dev/tcp/localhost/13000; do sleep 0.5; done'

ข้อแตกต่างคือถ้าไม่มีการเชื่อมต่อระหว่าง15s- มันจะไม่วนซ้ำตลอดไป แต่ออกด้วยรหัสข้อผิดพลาด

สิ่งนี้มีประโยชน์ในสคริปต์เริ่มต้นเพื่อรอความพร้อม / ความพร้อมใช้งานของบริการหลังจากเริ่มต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.