來自公眾號:高性能服務器開發(fā)
lsof 命令是 Linux 系統(tǒng)的擴展工具,它的含義是 list opened filedesciptor (列出已經打開的文件描述符),在 Linux 系統(tǒng)中,所有的與資源句柄相關的東西都可以統(tǒng)一抽象成文件描述符(filedescriptor,簡稱 fd)。一個文件句柄是一個 fd,一個 socket 對象也可以稱之為 fd 等等。 默認情況下,系統(tǒng)是不存在這個命令的,你需要安裝一下,使用如下命令安裝: yum install lsof
我們來看一下這個命令的使用效果: COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root cwd DIR 202,1 4096 2 / nscd 453 469 nscd 8u netlink 0t0 11017 ROUTE nscd 453 470 nscd cwd DIR 202,1 4096 2 / nscd 453 470 nscd rtd DIR 202,1 4096 2 / nscd 453 470 nscd txt REG 202,1 180272 146455 /usr/sbin/nscd nscd 453 470 nscd mem REG 202,1 217032 401548 /var/db/nscd/hosts nscd 453 470 nscd mem REG 202,1 90664 132818 /usr/lib64/libz.so.1.2.7 nscd 453 470 nscd mem REG 202,1 68192 133155 /usr/lib64/libbz2.so.1.0.6 nscd 453 470 nscd mem REG 202,1 153192 133002 /usr/lib64/liblzma.so.5.0.99 nscd 453 470 nscd mem REG 202,1 91496 133088 nscd 453 471 nscd 5u a_inode 0,9 0 4796 [eventpoll] nscd 453 471 nscd 6r REG 202,1 217032 401548 /var/db/nscd/hosts nscd 453 471 nscd 7u unix 0xffff880037497440 0t0 11015 /var/run/nscd/socket nscd 453 471 nscd 8u netlink 0t0 11017 ROUTE imgserver 611 zhangyl cwd DIR 202,1 4096 1059054 /home/zhangyl/flamingoserver imgserver 611 zhangyl rtd DIR 202,1 4096 2 / imgserver 611 zhangyl txt REG 202,1 4788917 1057044 /home/zhangyl/flamingoserver/imgserver imgserver 611 zhangyl 24u a_inode 0,9 0 4796 [eventfd] imgserver 611 zhangyl 25u IPv4 55707643 0t0 TCP *:commtact-http (LISTEN) imgserver 611 zhangyl 26r CHR 1,3 0t0 4800 /dev/null imgserver 611 613 zhangyl 32w REG 202,1 131072 2754609 /home/zhangyl/flamingoserver/imgcache/258bfb8945288a117d98d440986d7a03
結果顯示中列出了各個進程打開的各種 fd 類型,對于 Uinx Socket,lsof 命令會顯示出其詳細的路徑,打開的文件 fd 亦是如此。 使用 lsof 命令有三點需要注意: 默認情況下,lsof 的輸出比較多,我們可以使用 grep 命令過濾我們想要查看的進程打開的 fd 信息,如: lsof -i | grep myapp
或者使用 lsof -p pid 也能過濾出指定的進程打開的 fd 信息: [root@iZ238vnojlyZ ~]# lsof -p 26621 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME chatserve 26621 zhangyl cwd DIR 202,1 4096 1059054 /home/zhangyl/flamingoserver chatserve 26621 zhangyl rtd DIR 202,1 4096 2 / chatserve 26621 zhangyl txt REG 202,1 8027035 1051942 /home/zhangyl/flamingoserver/chatserver chatserve 26621 zhangyl mem REG 202,1 61928 141417 /usr/lib64/libnss_files-2.17.so chatserve 26621 zhangyl mem REG 202,1 44096 143235 /usr/lib64/librt-2.17.so chatserve 26621 zhangyl mem REG 202,1 19520 137064 /usr/lib64/libdl-2.17.so chatserve 26621 zhangyl mem REG 202,1 2112384 132824 /usr/lib64/libc-2.17.so chatserve 26621 zhangyl mem REG 202,1 142304 132850 /usr/lib64/libpthread-2.17.so chatserve 26621 zhangyl mem REG 202,1 88720 135291 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 chatserve 26621 zhangyl mem REG 202,1 1141560 137077 /usr/lib64/libm-2.17.so chatserve 26621 zhangyl mem REG 202,1 999944 140059 /usr/lib64/libstdc++.so.6.0.19 chatserve 26621 zhangyl mem REG 202,1 9879756 269001 /usr/lib64/mysql/libmysqlclient.so.20.3.4 chatserve 26621 zhangyl mem REG 202,1 164440 133622 /usr/lib64/ld-2.17.so chatserve 26621 zhangyl 0u CHR 1,3 0t0 4800 /dev/null chatserve 26621 zhangyl 1u CHR 1,3 0t0 4800 /dev/null chatserve 26621 zhangyl 2u CHR 1,3 0t0 4800 /dev/null chatserve 26621 zhangyl 3u a_inode 0,9 0 4796 [eventpoll] chatserve 26621 zhangyl 4u a_inode 0,9 0 4796 [timerfd] chatserve 26621 zhangyl 5u a_inode 0,9 0 4796 [eventfd] chatserve 26621 zhangyl 7u a_inode 0,9 0 4796 [eventpoll]
lsof 命令只能查看到當前用戶有權限查看到的進程 fd 信息,對于其沒有權限的進程,最右邊一列會顯示 “Permission denied”。如下所示: sshd 26759 root cwd unknown /proc/26759/cwd (readlink: Permission denied) sshd 26759 root rtd unknown /proc/26759/root (readlink: Permission denied) sshd 26759 root txt unknown /proc/26759/exe (readlink: Permission denied) sshd 26759 root NOFD /proc/26759/fd (opendir: Permission denied) bash 26761 root cwd unknown /proc/26761/cwd (readlink: Permission denied) bash 26761 root rtd unknown /proc/26761/root (readlink: Permission denied) bash 26761 root txt unknown /proc/26761/exe (readlink: Permission denied) bash 26761 root NOFD /proc/26761/fd (opendir: Permission denied)
lsof 命令第一欄進程名在顯示的時候,默認顯示前 n 個字符,這樣如果我們需要顯示完整的進程名以方便過濾的話,可以使用 +c 選項。用法如下: #最左側的程序名最大顯示 15 個字符 [zhangyl@iZ238vnojlyZ ~]$ lsof +c 15
當然,如果你設置值太大, lsof 便不會采用你設置的最大值,而是使用默認最大值。
上文也介紹了,socket 也是一種 fd,如果需要僅顯示系統(tǒng)的網絡連接信息,使用的是 -i 選項即可,這個選項可以形象地顯示出系統(tǒng)當前的出入連接情況: 
看到圖中的連接方向了吧? 當然,和 netstat 命令一樣,lsof -i 默認也會顯示 ip 地址和端口號的別名,我們只要使用 -n 和 -P 選項就能相對應地顯示 ip 地址和端口號了,綜合起來就是 lsof -Pni: 
|