如何殺死特定埠上執行的程序?
概述
在使用 Linux 時,通常需要停止某個程序使用特定的 TCP/IP 協議。例如,您可能正在執行一個監聽 HTTP 請求的應用程式,並且不希望它監聽埠 80(標準 HTTP 埠)。您可以使用 netstat 命令檢視當前哪些程序正在使用埠 -
$ netstat -lntp | grep :80 tcp6 0 0 :::80 :::* LISTEN 8072/httpd tcp4 0 0 ::ffff:127.0.0.1:80 :::::80 8069/httpd tcp6 0 127.0.0.5:53 :::* LISTEN 903/named udp6 0 0 :::22 :::* LISTEN 4963/sshd
我們將探討如何識別使用其埠的程序以及如何終止它們。我們還將瞭解如何殺死所有監聽特定埠的程序。
使用埠識別程序
netstat 命令可以幫助我們識別哪些程序正在監聽給定埠。-n 標記告訴 netstat 不要列印有關連線的任何資訊。如果我們只想瞭解是否有任何程序在監聽,這將非常有用。
準備示例
在開始測試識別和殺死在埠上執行的程序的一些策略之前,讓我們使用 socat 準備一些程序 -
$ socat sctp-listen:9999,bind=127.0.0.1 stdout & [1] 6424 $ socat tcp-listen:9999,bind=127.0.0.1 stdout & [2] 6431 $ socat udp-listen:9999,bind=127.0.0.1 stdout & [3] 6438
在這裡,我們使用埠 9999 和協議 SCTP、TCP 和 UDP 分別建立了三個程序。
使用fuser命令
fuser命令是終止程序的一個很好的工具。我們只需要使用 -k 引數。
讓我們使用 TCP 協議殺死程序 -
$ fuser -k 9999/tcp 9999/tcp: 6431
這裡,9000/udp 表示法是 -u udp 9000 的簡寫。
當查詢使用除 tcp 或 udp 以外的協議的程序時,我們無法使用 fusertop。
使用kill命令
我們需要使用“kill”(終止)函式來終止程序。但是,在這樣做之前,我們必須首先透過指定其埠和協議來識別程序的 PID。
當我們談論“kill”命令時,通常指的是程式 /bin/kill。但是,無論我們指的是程式 /usr/bin/kill 還是 shell 內建的 kill,它們都可以向正在執行的程序傳送特定型別的訊號。
lsof命令
您可以使用 lsof 命令檢視程序開啟的檔案資訊。
讓我們使用 kill 與 lsof 結合,透過傳送 UDP 資料包來終止程序。
$ lsof -i udp:9999 | awk '/9999/{print $2}' | xargs kill
在 lsof 部分,我們使用了 -i 引數來使用語法 [46][protocol][@hostname|hostaddr][:service|port] 過濾使用該埠的程序。在我們的例子中,我們使用了 protocol:port
我們使用了 awk 來搜尋在特定 TCP/IP 地址(在本例中為 9999)上執行的程序,然後只打印出 PID。使用 xargs 和 kill 終止了這些程序。
ss和netstat命令
由於 sctp 和 netstat 使用 SCTP 協議列出程序,讓我們結束最後一個程序 -
$ ss -Slp | grep -Po ':9999\s.*pid=\K\d+(?=,)' | xargs kill
要列出應用程式的監聽埠,請使用帶 -l 引數的 ss 實用程式。您還可以透過新增 -p 引數來指定哪些程序正在使用每個埠。最後,您可以透過指定 -S 引數來檢視 SCTP(流控制傳輸協議)連線。
我們使用了 sed 刪除了除字串 pid=" 和逗號 "," 之間的數字以外的所有內容。
我們也可以透過執行 netcat 使用另一種方法 -
$ netstat -Slp | grep -Po ':9999\s.*LISTEN.*?\K\d+(?=/)' | xargs kill
我們搜尋了字串“LISTEN”和字元“/”之間的數字列表。
從這些示例中我們可以看到,netcat 和 netcat6 都支援除 TCP/IP 之外的其他協議,因此它們有助於我們拓寬對網路的視野。但是,由於 netcat 已棄用,我們應該優先使用 nc 命令。
結論
我們討論了幾種使用特定埠殺死程序的方法。
我們首先使用了 fuser 命令。我們使用其埠號和協議查詢正在執行的程式的 PID,然後使用 kill 命令終止關聯的程式。