Bagaimana saya memberi tahu skrip untuk menunggu proses untuk mulai menerima permintaan pada port?

33

Saya memerlukan perintah yang akan menunggu proses untuk mulai menerima permintaan pada port tertentu.

Apakah ada sesuatu di linux yang melakukan itu?

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

...
Akan
sumber

Jawaban:

52

Tes terbaik untuk melihat apakah server menerima koneksi adalah dengan benar-benar mencoba menghubungkan. Gunakan klien biasa untuk protokol apa pun yang dibicarakan oleh server Anda dan coba perintah no-op.

Jika Anda menginginkan klien TCP atau UDP yang ringan, Anda dapat mengemudi hanya dari shell, gunakan netcat . Cara memprogram percakapan tergantung pada protokol; banyak protokol yang membuat server menutup koneksi pada input tertentu, dan netcat kemudian akan keluar.

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

Anda juga dapat memberitahu netcat untuk keluar setelah membuat koneksi. Ini mengembalikan 1 jika tidak ada koneksi dan 0 jika ada jadi kami meniadakan outputnya. Bergantung pada versi netcat Anda, itu mungkin mendukung satu atau kedua perintah berikut:

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

Pendekatan alternatif adalah menunggu proses server untuk membuka soket pendengaran.

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

Jika Anda menggunakan Mac OS, netstat menggunakan format output yang sedikit berbeda, jadi Anda ingin yang berikut:

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

Atau Anda mungkin ingin menargetkan ID proses tertentu:

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

Saya tidak bisa memikirkan cara untuk bereaksi terhadap proses mulai mendengarkan soket (yang akan menghindari pendekatan polling) singkat menggunakan ptrace.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Saya pikir netcat adalah jawabannya, jadi terima kasih. Untuk memperjelas, apa yang saya coba lakukan adalah menulis skrip sebagai bagian dari prosedur load balancing. Saya perlu memulai suatu proses, menunggu sampai menerima permintaan pada port dan kemudian mematikan yang asli. Jika ada cara yang lebih baik untuk melakukan ini, daripada menulis skrip saya sendiri, saya semua mendengar.
Will
@ Akan: Itu pertanyaan yang sangat berbeda! Saya sudah menulis jawaban yang berbeda.
Gilles 'SO berhenti makhluk jahat'
1
Saya suka solusi netcat juga. Saya memiliki skrip yang menggunakan nc -w 2 </dev/null >/dev/null- jika koneksi membutuhkan waktu lebih dari 2 detik, itu mati dan gagal - yang berguna untuk penggunaan saya.
ephemient
FYI, saya tidak bisa mendapatkan 'sementara nc -q 1 localhost 13000 </ dev / null; tidur 10; dilakukan satu untuk bekerja. Itu hanya kembali segera. Yang pertama berfungsi dengan baik. Terima kasih!
Ellis Percival
@Flyte nc -q 1 localhost 13000 </dev/nullsegera kembali jika tidak ada server yang mendengarkan, tetapi ia kembali dengan kode kesalahan, sehingga loop membuatnya tidur dan coba lagi beberapa detik kemudian.
Gilles 'SANGAT berhenti menjadi jahat'
17

Jika Anda memiliki bash dan coreutils (mis. Batas waktu, tidur), tetapi tidak nc / lsof / netstat, Anda dapat menggunakan solusi ini yang menggunakan soket bash magic tcp:

while ! timeout 1 bash -c "echo > /dev/tcp/localhost/13000"; do sleep 10; done
kanaka
sumber
Untuk menguraikan, Bash memiliki fitur opsional untuk menghubungkan ke soket TCP menggunakan "pengalihan jaringan" - gnu.org/software/bash/manual/html_node/…
johntellsall
7

Mengikuti contoh sebelumnya dengan bashtcp sockets magic, berikut adalah versi yang disempurnakan yang menunggu koneksi selama waktu terbatas.

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

Perbedaannya adalah bahwa jika koneksi tidak tersedia selama 15s, - itu tidak akan berulang tetapi keluar dengan kode kesalahan.

Ini berguna dalam skrip init untuk menunggu kesiapan / ketersediaan layanan setelah startup.

arma
sumber