Bir komut dosyasına bir işlemin bağlantı noktasında istekleri kabul etmeye başlamasını beklemesini nasıl söylerim?


33

Belirli bir bağlantı noktasında istekleri kabul etmeye başlamak için bir işlem için bekleyecek bir komuta ihtiyacım var.

Linux'ta bunu yapan bir şey var mı?

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

...

Yanıtlar:


52

Bir sunucunun bağlantıları kabul edip etmediğini görmek için en iyi test aslında bağlanmayı denemektir. Sunucunuzun konuşacağı protokol için düzenli bir istemci kullanın ve no-op komutunu deneyin.

Hafif bir TCP veya UDP istemcisi istiyorsanız, sadece kabuktan sürerek netcat kullanın . Bir konuşmanın nasıl programlanacağı protokole bağlıdır; birçok protokol sunucunun belirli bir girişteki bağlantıyı kapatmasını sağlar ve netcat bundan sonra çıkar.

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

Netcat'a bağlantı kurduktan sonra çıkmasını da söyleyebilirsiniz. Bağlantı yoksa 1, eğer varsa 0 döndürür, çıktısını olumsuzlarız. Netcat sürümünüze bağlı olarak, aşağıdaki komutlardan birini veya her ikisini de destekleyebilir:

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

Alternatif bir yaklaşım, sunucu işleminin bir dinleme soketi açmasını beklemektir.

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

Mac OS'taysanız, netstat biraz farklı bir çıktı formatı kullanır, bu nedenle aşağıdaki bilgiyi kullanmak istersiniz:

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

Veya belirli bir işlem kimliğini hedeflemek isteyebilirsiniz:

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

Soketi dinlemeye başlayan (yoklama yaklaşımından kaçınacak olan) sürece kısa sürede tepki vermenin hiçbir yolu düşünemiyorum ptrace.


Bence Netcat cevaptır, teşekkürler. Netleştirmek için, yapmaya çalıştığım şey yük dengeleme prosedürünün bir parçası olarak bir senaryo yazmak. Bir işlem başlatmam gerekiyor, bağlantı noktasında istekleri kabul etmesini bekleyip orjinali kapatmam gerekiyor. Bunu yapmanın daha iyi yolları varsa, kendi senaryomu yazmak yerine, hep kulağım.
Will

@ Will: Bu çok farklı bir soru! Farklı bir cevap yazdım.
Gilles 'SO- kötülük olmayı bırak'

1
Ben de netcat çözümünü severim. Kullandığım bir komut dosyası var nc -w 2 </dev/null >/dev/null- eğer bağlantı 2 saniyeden fazla sürerse, zaman aşımına uğradı ve başarısız oldu - ki bu benim kullanımım için kullanışlıdır.
efemient

Bilginize, 'alamadım' nc -q 1 localhost 13000 </ dev / null; 10 uyu; çalışmak için bitti. Sadece hemen döner. İlki olsa iyi çalışıyor. Teşekkürler!
Ellis Percival,

@Flyte nc -q 1 localhost 13000 </dev/nullhiçbir sunucu dinlemiyorsa hemen geri döner, ancak bir hata koduyla geri döner, bu nedenle döngü onu uyutur ve birkaç saniye sonra tekrar deneyin.
Gilles 'SO- kötü olmayı'

17

Eğer bash ve coreutils (örneğin zaman aşımı, uyku), ama nc / lsof / netstat yoksa, bash magic tcp soketlerini kullanan bu çözümü kullanabilirsiniz:

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

Ayrıntılı olarak, Bash, "ağ yönlendirmeleri" kullanarak TCP soketlerine bağlanma isteğe bağlı özelliğine sahiptir - gnu.org/software/bash/manual/html_node/…
johntellsall

7

Tcp soket büyü ile önceki örnekten sonra bash, burada sınırlı bir süre boyunca bağlantı için bekleyen gelişmiş bir sürüm.

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

Aradaki fark, eğer bağlantı sırasında mevcut değilse 15s, - sonsuza dek tekrarlanmayacak ancak hata koduyla çıkacak.

Bu, init komut dosyalarında, başlangıçtan sonra hizmet hazırlığı / kullanılabilirliğini beklemek için kullanışlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.