Windows PowerShell で Bash の kill lsof 相当を行う
Linux・Bash の世界だと、lsof コマンドでそのポート番号を使っているプロセスを調べて、ps で実行コマンドを調べたり kill したり、といったことができる。
# 8080 ポートを使っているプロセス ID は? → PID 995 と判明
$ lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
MainThrea 995 neo 21u IPv6 21578 0t0 TCP *:tproxy (LISTEN)
# PID 995 は何のコマンドが動いてる?
$ ps 995
PID TTY STAT TIME COMMAND
995 pts/4 Sl+ 0:00 node index.js
# `lsof` コマンドは PID だけを出力できる (`-t` オプション)
$ lsof -i:8080 -t
995
# `kill` コマンドに流し込めば一発でタスクキルできる
$ kill $(lsof -i:8080 -t)
コレと同等のことを、Windows 環境・PowerShell でやりたかったので、調べた。
# 方法 1 : `netstat` を使う
PS> netstat -ano | Select-String '0.0.0.0:8080'
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 7064
# `netstat` で PID だけ取り出す
PS> netstat -ano | Select-String '0.0.0.0:8080' | ForEach-Object { ($_ -split '\s+')[-1] }
7064
# 方法 2 : `Get-NetTCPConnection` で一発で取れる
PS> Get-NetTCPConnection -LocalPort 8080
LocalAddress LocalPort RemoteAddress RemotePort State AppliedSetting
------------ --------- ------------- ---------- ----- --------------
:: 8080 :: 0 Listen
# PID だけ取り出す
PS> Get-NetTCPConnection -LocalPort 8080 | Select-Object -ExpandProperty OwningProcess
7064
# PID を指定して実行されているコマンドを調べる
PS> Get-CimInstance Win32_Process -Filter 'ProcessId = 7064' | Select-Object ProcessId, Name, CommandLine
ProcessId Name CommandLine
--------- ---- -----------
7064 node.exe C:\nvm4w\nodejs\node.exe index.js
# ポート番号から直接実行コマンドを調べる
PS> Get-NetTCPConnection -LocalPort 8080 | ForEach-Object { Get-CimInstance Win32_Process -Filter 'ProcessId = $($_.OwningProcess)' } | Select ProcessId, Name, CommandLine
ProcessId Name CommandLine
--------- ---- -----------
7064 node.exe C:\nvm4w\nodejs\node.exe index.js
# ポート番号を指定してタスクキルに持ち込むなら以下のいずれかで良い
PS> netstat -ano | Select-String '0.0.0.0:8080' | ForEach-Object { ($_ -split '\s+')[-1] } | ForEach-Object { Stop-Process -Id $_ -Force }
PS> Stop-Process -Id (Get-NetTCPConnection -LocalPort 8080).OwningProcess -Force
PS> Stop-Process -Id (Get-NetTCPConnection -LocalPort 8080 | Select-Object -ExpandProperty OwningProcess) -Force
個人的には
PS> Get-NetTCPConnection -LocalPort 8080
PS> (Get-NetTCPConnection -LocalPort 8080).OwningProcess
だけ覚えておけばなんとかなるかも。