Làm cách nào để tôi biết một tập lệnh chờ đợi một quá trình bắt đầu chấp nhận các yêu cầu trên một cổng?


33

Tôi cần một lệnh sẽ chờ một quá trình để bắt đầu chấp nhận các yêu cầu trên một cổng cụ thể.

Có một cái gì đó trong linux mà làm điều đó?

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

...

Câu trả lời:


52

Thử nghiệm tốt nhất để xem máy chủ có chấp nhận kết nối hay không là thử kết nối. Sử dụng máy khách thông thường cho bất kỳ giao thức nào mà máy chủ của bạn nói và thử lệnh no-op.

Nếu bạn muốn một máy khách TCP hoặc UDP nhẹ, bạn có thể lái xe đơn giản từ hệ vỏ, hãy sử dụng netcat . Làm thế nào để lập trình một cuộc hội thoại phụ thuộc vào giao thức; nhiều giao thức có máy chủ đóng kết nối trên một đầu vào nhất định và sau đó netcat sẽ thoát.

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

Bạn cũng có thể yêu cầu netcat thoát sau khi thiết lập kết nối. Nó trả về 1 nếu không có kết nối và 0 nếu có vì vậy chúng tôi phủ nhận đầu ra của nó. Tùy thuộc vào phiên bản netcat của bạn, nó có thể hỗ trợ một hoặc cả hai lệnh sau:

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

Một cách tiếp cận khác là chờ quá trình máy chủ mở ổ cắm nghe.

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

Nếu bạn đang dùng Mac OS, netstat sử dụng định dạng đầu ra hơi khác, vì vậy bạn sẽ muốn có thông tin sau:

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

Hoặc bạn có thể muốn nhắm mục tiêu ID quy trình cụ thể:

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

Tôi không thể nghĩ ra bất kỳ cách nào để phản ứng với quá trình bắt đầu lắng nghe ổ cắm (điều này sẽ tránh cách tiếp cận bỏ phiếu) khi sử dụng ptrace.


Tôi nghĩ netcat là câu trả lời, vì vậy cảm ơn bạn. Để làm rõ, những gì tôi đang cố gắng làm là viết một kịch bản như là một phần của thủ tục cân bằng tải. Tôi cần bắt đầu một quá trình, đợi nó chấp nhận các yêu cầu trên cổng và sau đó tắt máy ban đầu. Nếu có những cách tốt hơn để làm điều này, thay vì viết kịch bản của riêng tôi, tôi sẽ nghe thấy.
Sẽ

@ Will: Đó là một câu hỏi rất khác! Tôi đã viết một câu trả lời khác nhau.
Gilles 'SO- ngừng trở nên xấu xa'

1
Tôi thích giải pháp netcat quá. Tôi có một tập lệnh sử dụng nc -w 2 </dev/null >/dev/null- nếu kết nối mất hơn 2 giây, nó hết thời gian và không thành công - rất hữu ích cho việc sử dụng của tôi.
ephemient

FYI, tôi không thể nhận được 'trong khi nc -q 1 localhost 13000 </ dev / null; ngủ 10; xong 'một để làm việc. Nó chỉ trở lại ngay lập tức. Cái đầu tiên hoạt động tốt mặc dù. Cảm ơn!
Ellis Percival

@Flyte nc -q 1 localhost 13000 </dev/nulltrả về ngay lập tức nếu không có máy chủ nào nghe, nhưng nó trả về với mã lỗi, vì vậy vòng lặp làm cho nó ngủ và thử lại vài giây sau.
Gilles 'SO- ngừng trở nên xấu xa'

17

Nếu bạn có bash và coreutils (ví dụ như thời gian chờ, thời gian ngủ), nhưng không phải nc / lsof / netstat, bạn có thể sử dụng giải pháp này sử dụng ổ cắm bash ma thuật bash:

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

Để giải thích, Bash có tính năng tùy chọn kết nối với các ổ cắm TCP bằng cách sử dụng "chuyển hướng mạng" - gnu.org/software/bash/manual/html_node/ phỏng
johntellsall 23/12/14

7

Theo ví dụ trước với bashma thuật ổ cắm tcp, đây là phiên bản nâng cao chờ kết nối trong khoảng thời gian giới hạn.

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

Sự khác biệt là nếu kết nối không khả dụng trong thời gian 15s, - nó sẽ không lặp lại mãi mà thoát khỏi mã lỗi.

Điều này rất hữu ích trong các tập lệnh init để chờ sẵn sàng / sẵn sàng dịch vụ sau khi khởi động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.