Як я можу сказати сценарію чекати, поки процес почне приймати запити на порт?


33

Мені потрібна команда, яка буде чекати, коли процес почне приймати запити на певному порті.

Чи є щось в Linux, що це робить?

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

...

Відповіді:


52

Найкращий тест на перевірку того, чи приймає сервер з'єднання - це насправді спробувати підключитися. Використовуйте звичайний клієнт для будь-якого протоколу, на якому розмовляє ваш сервер, і спробуйте команду без операції.

Якщо ви хочете легкий клієнт 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

Або ви хочете націлити певний ідентифікатор процесу:

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

Я не можу придумати жодного способу відреагувати на процес, починаючи слухати сокет (який би уникнув підходу опитування), не використовуючи ptrace.


Я думаю, що netcat - це відповідь, тому дякую. Щоб уточнити, що я намагаюся зробити, це написати сценарій як частину процедури балансування навантаження. Мені потрібно запустити процес, дочекатися, коли він прийме запити на порт, а потім вимкніть оригінал. Якщо є кращі способи зробити це, а не написати власний сценарій, я все вухо.
Буде чи

@Will: Це зовсім інше питання! Я написав іншу відповідь.
Жил 'ТАК - перестань бути злим'

1
Мені також подобається сітчастий розчин. У мене є сценарій, який використовує nc -w 2 </dev/null >/dev/null- якщо з'єднання триває більше 2 секунд, воно вичерпується та виходить з ладу - що зручно для мого використання.
ефеміент

FYI, я не можу отримати 'while nc -q 1 localhost 13000 </ dev / null; спати 10; зробив 'один на роботу. Це просто повертається негайно. Хоча перший працює чудово. Спасибі!
Елліс Персіваль

@Flyte nc -q 1 localhost 13000 </dev/nullповертається негайно, якщо жоден сервер не слухає, але він повертається з кодом помилки, тому цикл перебуває у режимі сну і повторіть спробу через кілька секунд.
Жиль "ТАК - перестань бути злим"

17

Якщо у вас є bash та coreutils (наприклад, тайм-аут, сон), але не nc / lsof / netstat, ви можете використовувати це рішення, яке використовує bash magic tcp sockets:

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

Після попереднього прикладу з bashTCP Sockets магії, ось це розширена версія , яка очікує з'єднання під час обмеженого періоду часу.

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

Різниця полягає в тому, що якщо підключення не було доступне протягом 15s, - воно не буде циклічно назавжди, а вийде з кодом помилки.

Це корисно в сценаріях init, щоб дочекатися готовності / доступності послуги після запуску.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.