プロセスを強制終了する必要がある場合があります(理由は重要ではありません)。そして、次のコマンドでそのプロセスを見つけることができることを私は知っています: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 KDEx64を実行しています
あなたの質問に文字通り答えて、これがlsof
によって表示された最後のPIDをリストする1つの方法です:
_lsof … | awk 'END {print $2}'
_
Awk は、入力を読み取り、それを1行ずつ処理するテキスト処理言語です。コードでは、_END {…}
_は、入力全体が処理された後、中括弧内のコードを実行し、最後の行で効果的に動作します。 _$2
_は、行の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
の出力を処理することも、 lsof
に_-F
_オプションを使用すると、単純なケースでは解析が少し難しくなりますが、(ほとんど)あいまいになりにくく、堅牢に解析しやすい出力が生成されます。たとえば、ポート8080でリッスンしているプロセスを強制終了する場合は、次の方法で実行できます。
_lsof -n -i :8080 -F | awk '
sub(/^p/,"") {pid = $0}
$0 == "n*:http-alt" {print pid}
' | xargs kill
_
sub
関数を呼び出すと、行の先頭にあるp
が空の文字列に置き換えられます。この置換が実行されると、コードブロック_{pid = $0}
_が実行されます。このように、pid
変数には、lsof
によって表示される最後のPID値が含まれます。 2番目のawk行は、行が正確に_"n*:http-alt"
_である場合、pid
変数の値を出力します。これは、すべてのインターフェイスのポート8080でリッスンしているソケットを報告するlsofの方法です。
この特定の基準は、実際には解析を必要としません(例として上に示しただけです)。指定されたポートでリッスンしているプロセスだけを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の部分のみを保持するため)、それを出力します。