Làm cách nào để kiểm tra xem một cổng cụ thể có được mở trên máy từ tập lệnh shell hay không và thực hiện hành động dựa trên đó?


24

Tôi đang chạy tập lệnh shell bên dưới của mình trên một máy mà máy chủ ứng dụng c ++ đang chạy trên cổng 8080 và trong tập lệnh shell tôi đang thực thi một URL và lưu trữ phản hồi đến từ URL đó trong biến DATA.

Nhưng giả sử nếu cùng một máy chủ ứng dụng ngừng hoạt động, thì nó sẽ không thể thực thi URL và sau đó nó sẽ in ra Retrying Againvà ngủ trong 30 giây và sau đó thực hiện lại cùng một url.

#!/bin/bash

HOSTNAME=$hostname
DATA=""
RETRY=15

echo $HOSTNAME

while [ $RETRY -gt 0 ]
do
    DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
    if [ $? -eq 0 ]
    then
        break
    else
        echo "Retrying Again" >&2

        # restart the server

        let RETRY-=1
        sleep 30
    fi
done

echo "Server is UP"

Và đây HOSTNAMElà tên máy chủ cục bộ của máy chủ mà tôi đang chạy tập lệnh shell ở trên.

Báo cáo vấn đề:-

Bây giờ những gì tôi đang cố gắng làm là, nếu máy chủ ngừng hoạt động, thì nó sẽ in ra Retrying Againđể sau đó tôi muốn kiểm tra xem cổng 8080có được mở $HOSTNAMEhay không. Nếu không, điều đó có nghĩa là máy chủ không hoạt động nên tôi muốn khởi động lại máy chủ bằng cách thực hiện lệnh này và sau đó ngủ trong 30 giây như được hiển thị ở trên trong tập lệnh shell.

/opt/app/test/start_stop.sh start

Điều này có thể làm ở đây trong kịch bản shell trên của tôi không?

Tôi đang chạy tập lệnh shell này trên Ubuntu 12.04.

Câu trả lời:


23

Chương trình lsofcho phép bạn kiểm tra các quá trình đang sử dụng các nguồn tài nguyên nào, như các tệp hoặc cổng.

Để hiển thị các quá trình đang nghe trên cổng 8080:

lsof -Pi :8080 -sTCP:LISTEN

Trong trường hợp của bạn, bạn muốn kiểm tra xem một quá trình có nghe trên 8080 hay không - giá trị trả về của lệnh này cho bạn biết điều đó. Nó cũng in pid của quá trình.

lsof -Pi :8080 -sTCP:LISTEN -t

Nếu bạn chỉ cần thử nghiệm, không có đầu ra, hãy chuyển hướng nó tới /dev/null:

if lsof -Pi :8080 -sTCP:LISTEN -t >/dev/null ; then
    echo "running"
else
    echo "not running"
fi


Nếu bạn sử dụng nhiều tên máy chủ lưu trữ với nhiều địa chỉ IP cục bộ, hãy chỉ định tên máy chủ giống như
lsof -Pi @someLocalName:8080 -sTCP:LISTEN


Cảm ơn Volker. Tôi đã thử điều này lsof -i :8080 -sTCP:LISTENvà tôi không nhận được bất cứ điều gì trên bảng điều khiển nhưng nếu tôi đang thử điều này netstat -tulpn | grep :8080thì tôi nhận được quy trình đang chạy trên cổng 8080 tại sao nó lại như vậy?
david

Đầu ra của là netstat -tulpn | grep :8080gì?
Volker Siegel

Đây là những gì tôi nhận được với netstat - david@machineA:/home/david$ netstat -tulpn | grep :8080 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 27530/test_server
david

Thật kỳ lạ, nếu tôi thử những thứ tương tự nó hoạt động. Có thể liên quan đến IPv6 ... hmmm.
Volker Siegel

Nó được liệt kê với lsof -iTCP -sTCP:LISTEN | grep 8080?
Volker Siegel

16

Cách đơn giản nhất trong bash. Kiểm tra nếu cổng của bạn đang mở.

(echo >/dev/tcp/localhost/8080) &>/dev/null && echo "TCP port 8080 open" || echo "TCP port 8080 close"

Thay thế tiếng vang với những gì bạn muốn.

Hoặc bạn có thể sử dụng nc.

nc -vz 127.0.0.1 8080

Trả về:

Kết nối với cổng 127.0.0.1 8080 [tcp / *] đã thành công


1
nclà một giải pháp tuyệt vời cho trường hợp sử dụng của tôi; cảm ơn vì đã gợi ý
Jon

1

Xây dựng câu trả lời của RJ, ghi chú nào nccũng hữu ích ... Không chỉ nchữu ích cho truy vấn dòng lệnh nhanh

 nc -z -v -w5 127.0.0.1 8080
localhost [127.0.0.1] 8080 (http-alt) : Connection refused

nhưng nó có thể được sử dụng mà không có -v nếu thứ dễ đọc của con người không phải là thứ bạn đang theo đuổi - ví dụ, để sử dụng trong tập lệnh (mã thoát sẽ cho biết cổng được mở hay đóng).

 nc -z 127.0.0.1 8080

 echo $?             
1
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.