Linuxでアプリケーションが使用中のポート番号を調べる

Linuxシステムを管理している人には常識的なことだと思うけど、アプリケーションが使用中のポート番号を調べる方法についてのメモ。今日某プロジェクトの実験用マシンの設定をしていた最中、あるサービスを起動したら「address already in use.」というエラーメッセージが出てきて調べたので。
アプリケーションが使用中のポート番号は「lsof」や「netstat」コマンドで調べることができる。lsofは「lists open files」の略で、プロセスが開いているファイルを列挙するコマンド。

$ ps aux | grep zsh
shin      1644   0.0  0.1   602692   2676 s000  S     1:09AM   0:00.12 -zsh
$ lsof -p 1644
COMMAND  PID USER   FD   TYPE DEVICE  SIZE/OFF      NODE NAME
zsh     1644 shin  cwd    DIR   14,2      1462    762478 /Users/shin
zsh     1644 shin  txt    REG   14,2    982000     22508 /bin/zsh
zsh     1644 shin  txt    REG   14,2    382836     81047 /usr/lib/zsh/4.3.4/zsh/zle.so
zsh     1644 shin  txt    REG   14,2     61748     81039 /usr/lib/zsh/4.3.4/zsh/parameter.so
zsh     1644 shin  txt    REG   14,2    219320     81025 /usr/lib/zsh/4.3.4/zsh/complete.so
zsh     1644 shin  txt    REG   14,2     59968     81052 /usr/lib/zsh/4.3.4/zsh/zutil.so
zsh     1644 shin  txt    REG   14,2    108168     81026 /usr/lib/zsh/4.3.4/zsh/complist.so
zsh     1644 shin  txt    REG   14,2    118472     81027 /usr/lib/zsh/4.3.4/zsh/computil.so
zsh     1644 shin  txt    REG   14,2   1059776   1652710 /usr/lib/dyld
zsh     1644 shin  txt    REG   14,2 134479872   1808792 /private/var/db/dyld/dyld_shared_cache_i386
zsh     1644 shin    0u   CHR   16,0 0t1904182 153214596 /dev/ttys000
zsh     1644 shin    1u   CHR   16,0 0t1904182 153214596 /dev/ttys000
zsh     1644 shin    2u   CHR   16,0 0t1904182 153214596 /dev/ttys000
zsh     1644 shin    3u   REG   14,2      4396   1854125 /private/var/run/utmpx
zsh     1644 shin   10u   CHR   16,0     0t177 153214596 /dev/ttys000

このコマンドを使ってあるポート番号を使用しているアプリケーションを特定するには、「-i:PORT_NUM」を引数に与えて実行する。root権限で実行する必要がある。

$ sudo lsof -i:8443
COMMAND   PID   USER   FD   TYPE DEVICE SIZE NODE NAME
java     4249 globus    5u  IPv4 650367       TCP *:8443 (LISTEN)
java    18389 globus    5u  IPv4 650367       TCP *:8443 (LISTEN)
...

しかし、lsofを使ってみたところ、プロセスがフォークしてたり(スレッドを使っている場合もか?)すると大量のプロセスが出力されて見づらい。そこでもう少し調べたところ、netstatでも「-anp」オプションを指定すると取得できることがわかった。

$ sudo netstat -anp | grep 8443
Proto Recv-Q Send-Q Local Address  Foreign Address  State       PID/Program name   
tcp        0      0 0.0.0.0:8443   0.0.0.0:*        LISTEN      25354/java          
tcp        0      0 X.X.X.X:8443   X.X.X.X:36151    TIME_WAIT   -                   
tcp        0      0 X.X.X.X:8443   X.X.X.X:36152    TIME_WAIT   -                   
tcp        0      0 X.X.X.X:8443   X.X.X.X:36163    TIME_WAIT   -                   
tcp        0      0 X.X.X.X:8443   X.X.X.X:36164    TIME_WAIT   -                   
tcp        0      0 X.X.X.X:8443   X.X.X.X:36171    TIME_WAIT   -                   
tcp        0      0 X.X.X.X:8443   X.X.X.X:36172    TIME_WAIT   -                   
tcp        0      0 X.X.X.X:8443   X.X.X.X:36173    TIME_WAIT   -                   
tcp        0      0 X.X.X.X:8443   X.X.X.X:36174    TIME_WAIT   -

(見やすさのために1行目は表示、X.X.X.XはIPアドレス)

netstatならばプログラムがPID 25354のJavaだとすぐにわかって便利。ちなみに「-anp」の「-a」はSend、Recvの両方を表示、「-n」はアドレス、ホスト、ユーザ名を数値で表示、「-p」はソケットが属しているPIDとプログラムを表示するって意味。
システム管理としてはだいぶ基本的なことだけど、今までないがしろにしてきたので忘れないようにメモ。
参考
netstatコマンドでポートを利用しているプロセスを調べる - 管理者必見! ネットワーク・コマンド集:ITpro
@IT:特定のポートをオープンしているプロセスを調べるには