用於殺死先前命令提供的特定 PID 的命令
有時我需要殺死一個程序(原因並不重要)。而且我知道我可以使用以下命令找到該程序:
lsof -i :8080
,作為我的候選人,輸出表中的最後一個程序。例如,如果我執行命令,將出現如下輸出:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 15112 dani 70u IPv4 3178183 0t0 TCP localhost:39998->localhost:http-alt (CLOSE_WAIT) java 15112 dani 137u IPv4 3181607 0t0 TCP localhost:39999->localhost:http-alt (CLOSE_WAIT) java 15112 dani 138u IPv4 3181608 0t0 TCP localhost:40000->localhost:http-alt (CLOSE_WAIT) java 15112 dani 139u IPv4 3181609 0t0 TCP localhost:40001->localhost:http-alt (CLOSE_WAIT) java 15112 dani 140u IPv4 3181610 0t0 TCP localhost:40002->localhost:http-alt (CLOSE_WAIT) java 19509 dani 50u IPv6 4617361 0t0 TCP *:http-alt (LISTEN) java 19509 dani 52u IPv6 6642445 0t0 TCP localhost:http-alt->localhost:42996 (CLOSE_WAIT)
所以,我的目標是PID 19509。使用管道,我如何挑選最後一行的 PID?
我想達到一個命令
lsof -i :8080 | something here to get the PID | kill -9
我正在執行 Linux Mint KDE x64
從字面上回答您的問題,這是列出由 顯示的最後一個 PID 的一種方法
lsof
:lsof … | awk 'END {print $2}'
awk是一種文本處理語言,它讀取輸入並逐行處理。在程式碼中,
END {…}
在處理完整個輸入後執行大括號中的程式碼,並在最後一行進行有效操作。$2
是該行的第二個以空格分隔的欄位。這裡有一些殺死它的方法(每行獨立工作):
kill $(lsof … | awk 'END {print $2}') lsof … | awk 'END {print $2}' | xargs kill lsof … | awk 'END {system("kill " $2)}'
但是,我不同意您的說法,即正確的殺死過程總是最後一個。
lsof
通過增加PID來顯示程序,這是沒有意義的。即使在按順序分配程序 ID 的系統上(並非所有 Unix 變體,甚至所有 Linux 安裝都不是這種情況),一旦達到最大值(通常為 32767),它們也會包裝。因此,通過比較 PID 來決定程序是沒有意義的。您需要一些其他資訊來決定要終止哪個程序。根據您所追求的資訊類型以及您的輸出是否可能包含“奇怪”字元(如文件或程序名稱中的空格),您可以使用 awk 之類的工具來處理 的輸出
lsof
,或者您可以使用產生輸出的-F
選項lsof
在簡單的情況下更難解析,但(幾乎)不容易產生歧義並且更容易健壯地解析。例如,如果你想殺死任何在埠 8080 上監聽的程序,你可以這樣做:lsof -n -i :8080 -F | awk ' sub(/^p/,"") {pid = $0} $0 == "n*:http-alt" {print pid} ' | xargs kill
對函式的呼叫在行首
sub
替換為空字元串。p
如果執行此替換,則執行程式碼塊{pid = $0}
;這樣,pid
變數包含由 顯示的最後一個 PID 值lsof
。如果第二行是 awk 則列印pid
變數的值"n*:http-alt"
,這是 lsof 報告在所有介面上偵聽埠 8080 的套接字的方式。這個特定的標準實際上不需要任何解析(我只是在上面展示了它作為一個例子)。您可以
lsof
只顯示在指定埠上偵聽的程序:lsof -n -a -iTCP:8080 -sTCP:LISTEN -Fp | sed 's/^p//' | xargs kill
或者,為此,您可以
netstat
改用。netstat -lnpt | awk '$4 ~ /:8080$/ {sub(/\/.*/, "", $7); print $7}'
awk 程式碼說明:如果第 4 列以 結尾
:8080
,則替換第/
7 列中第一列之後的所有內容(刪除程序名稱部分並僅保留 PID 部分),然後列印。