lsof命令是什么
lsof
lists on its standard output file information about files opened by processes
被打开的文件可以是
- regular file
- directory
- 网络文件系统的文件
- 字符设备文件
- (函数)共享库
- 管道,命名管道
- 符号链接
- a stream or a network file (Internet socket, NFS file or UNIX domain socket.
Columns 含义
- COMMAND:进程的名称
- PID:进程标识符
- PPID:父进程标识符(需要指定-R参数)
- USER:进程所有者
- PGID:进程所属组
- FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
- cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
- txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
- er:FD information error (see NAME column)
- ltx:shared library text (code and data)
- mxx :hex memory-mapped type number xx.
- mem:memory-mapped file
- mmap:memory-mapped device
- pd:parent directory
- rtd:root directory;
- v86 VP/ix mapped file;
- 0:表示标准输出
- 1:表示标准输入
- 2:表示标准错误
一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等
- u:表示该文件被打开并处于读取/写入模式
- r:表示该文件被打开并处于只读模式
- w:表示该文件被打开并处于
- 空格:表示该文件的状态模式为unknow,且没有锁定
- -:表示该文件的状态模式为unknow,且被锁定
同时在文件状态模式后面,还跟着相关的锁
-
N:for a Solaris NFS lock of unknown type;
-
r:for read lock on part of the file;
-
R:for a read lock on the entire file;
-
w:for a write lock on part of the file;(文件的部分写锁)
-
W:for a write lock on the entire file;(整个文件的写锁)
-
u:for a read and write lock of any length;
-
U:for a lock of unknown type;
-
x:for an SCO OpenServer Xenix lock on part of the file;
-
X:for an SCO OpenServer Xenix lock on the entire file;
-
space:if there is no lock.
-
TYPE:文件类型,如DIR、REG等,常见的文件类型
- DIR:表示目录
- CHR:表示字符类型
- BLK:块设备类型
- UNIX: Unix domain socket
- FIFO:先进先出 (FIFO) 队列
- IPv4:网际协议 (IP) 套接字
-
DEVICE:指定磁盘的名称
-
SIZE:文件的大小
-
NODE:索引节点(文件在磁盘上的标识)
-
NAME:打开文件的确切名称
Usage
列出打开了某个文件的所有进程
如果不加任何参数,就会打开所有被打开的文件,建议加上特定参数来查看特定信息。
# list all open files
$ lsof
# To find the process that has /u/abe/foo open
$ lsof [/u/abe/foo]
# To list all open files on device /dev/hd4, use:
$ lsof /dev/hd4
# list the processes opening a file via Unix domain socket
$ lsof /tmp/echo.sock
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
___go_bui 13785 shiwei 3u unix 0xcc59970df46632e9 0t0 /tmp/echo.sock
___go_bui 13785 shiwei 7u unix 0xcc59970de99c6161 0t0 /tmp/echo.sock
比如,我用QuickTime播放一个视频,然后列出打开了该视频文件的进程:
$ lsof 584.mp4
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
QuickTime 9199 wei.shi 12r REG 1,5 3846660 53157818 584.mp4
-u [user_name]
- 根据用户名
# 列出当前用户打开的所有文件
$ lsof -u [username]
# 列出不是用户打开的所有文件
$ lsof -u ^[username]
-c <process_name>
- 根据进程名称
-c <process_name>
: selects the listing of files for processes executing the command that begins with the characters ofprocess_name
.
$ ps -ef | grep grafana-s
2061703888 665 1 0 5Mar21 ?? 1:52.91 /usr/local/opt/grafana/bin/grafana-server --config /usr/local/etc/grafana/grafana.ini
$ lsof -c grafana-s
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
grafana-s 665 wei.shi cwd DIR 1,5 160 30544021 /usr/local/var/lib/grafana
grafana-s 665 wei.shi txt REG 1,5 58030576 50725322 /usr/local/Cellar/grafana/7.3.5/bin/grafana-server
grafana-s 665 wei.shi txt REG 1,5 28604 60813977 /Library/Preferences/Logging/.plist-cache.USiJWGsl
grafana-s 665 wei.shi txt REG 1,5 32768 60603174 /private/var/db/mds/messages/2061703888/se_SecurityMessages
grafana-s 665 wei.shi txt REG 1,5 1568368 1152921500312538092 /usr/lib/dyld
grafana-s 665 wei.shi txt REG 1,5 28620288 1152921500312405449 /usr/share/icu/icudt64l.dat
grafana-s 665 wei.shi 0r CHR 3,2 0t0 310 /dev/null
grafana-s 665 wei.shi 1u REG 1,5 177523 30544426 /usr/local/var/log/grafana/grafana-stdout.log
...
注意,这里的process_name
采用的是模糊匹配,这意味着如果
$ lsof -c grafan
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
grafana-s 665 wei.shi cwd DIR 1,5 160 30544021 /usr/local/var/lib/grafana
grafana-s 665 wei.shi txt REG 1,5 58030576 50725322 /usr/local/Cellar/grafana/7.3.5/bin/grafana-server
grafana-s 665 wei.shi txt REG 1,5 28604 60813977 /Library/Preferences/Logging/.plist-cache.USiJWGsl
grafana-s 665 wei.shi txt REG 1,5 32768 60603174 /private/var/db/mds/messages/2061703888/se_SecurityMessages
grafana-s 665 wei.shi txt REG 1,5 1568368 1152921500312538092 /usr/lib/dyld
grafana-s 665 wei.shi txt REG 1,5 28620288 1152921500312405449 /usr/share/icu/icudt64l.dat
grafana-s 665 wei.shi 0r CHR 3,2 0t0 310 /dev/null
grafana-s 665 wei.shi 1u REG 1,5 177523 30544426 /usr/local/var/log/grafana/grafana-stdout.log
也是会得到一样的结果。
-p [pid]
- 根据进程号
$ lsof -p [pid]
-i
- 根据网络连接
# 列出所有的网络连接
$ lsof -i
# Usage
$ lsof -i[46][protocol][@hostname|hostaddr][:service|port]
where:
- 46 specifies the IP version, IPv4 or IPv6 that applies to the following address. ‘6’ may be be specified only if the UNIX dialect supports IPv6. If neither ‘4’ nor ‘6’ is specified, the following address applies to all IP versions.
- protocol is a protocol name - TCP, UDP
- hostname is an Internet host name. Unless a specific IP version is specified, open network files associated with host names of all versions will be selected.
- hostaddr is a numeric Internet IPv4 address in dot form; or an IPv6 numeric address in colon form, enclosed in brackets, if the UNIX dialect supports IPv6. When an IP version is selected, only its numeric addresses may be specified.
- service is an /etc/services name - e.g., smtp - or a list of them.
- port is a port number, or a list of them.
TCP/UDP 相关
# 列出所有 TCP 网络连接信息
$ lsof -i tcp
# 列出所有 UDP 网络连接信息
$ lsof -i udp
$ lsof -n -iTCP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
svnserve 11552 weber 3u IPv4 3799399 0t0 TCP *:svn (LISTEN)
redis-ser 25501 weber 4u IPv4 113150 0t0 TCP 127.0.0.1:6379 (LISTEN)
端口相关
# 根据端口列出正在使用该端口的进程
$ lsof -i:[port]
# e.g.,
$ lsof -i:3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
grafana-s 665 wei.shi 14u IPv6 0x278374e8fe3d2547 0t0 TCP *:hbci (LISTEN)
# 列出使用某个特定的 UDP 端口的进程
$ lsof -iUDP:55
# 列出使用某个特定的 UDP 端口的进程
$ lsof -iTCP:80
IPV4 and IPV6
If -i4
or -i6
is specified with no following address, only files of the indicated IP version, IPv4 or IPv6, are displayed.
# 只显示IPV4
$ lsof -i4
# 只显示IPV6
$ lsof -i6
# Or
$ lsof -i 6
指定 hostname
# Internet IPv4 host address 1.2.3.4
$ lsof -i@1.2.3.4
# Internet IPv6 host address 3ffe:1ebc::1, port 1234
$ lsof -i@[3ffe:1ebc::1]:1234
# list all files using any protocol on ports 513, 514, or 515 of host wonderland.cc.purdue.edu, use:
$ lsof -i @wonderland.cc.purdue.edu:513-515
指定TCP/UDP状态
# Find the process that is listening on a local TCP port:
$ lsof -iTCP -sTCP:LISTEN
# list network files with all UDP states except Idle, use:
$ lsof -iUDP -sUDP:Idle
+D/+d/-d [folder_path]
- 根据文件夹路径
+d [folder_path]
: search for all open instances of inputed directorys and the files and directories it contains at its top level-d [file_number]
: specifies a list of file descriptors (FDs) to exclude from or include in the output listing.+D [folder_path]
: search for all open instances of inputed directory and all the files and directories it contains to its complete depth.
# 列出打开了该文件夹及该文件夹下文件/文件夹的进程(不递归)
$ lsof +d [folder_path]
# 列出打开了该文件夹及该文件夹下文件/文件夹的进程(递归)
$ lsof +D [folder_path]
$ tree sw_test
sw_test
└── sw_test2
└── sw_test3
2 directories, 0 files
# 在一个 Shell 进到一个文件夹
$ cd sw_test/sw_test2
# 显示当前 Shell(zsh)的 PID
$ echo $$
10236
# 在另一个 Shell 进到一个文件夹
$ cd sw_test/sw_test2/sw_test3
# 显示当前 Shell(zsh)的 PID
$ echo $$
10393
# 另启动一个 Shell
$ lsof +d sw_test
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zsh 10236 wei.shi cwd DIR 1,5 64 61411500 sw_test/sw_test2
$ lsof +D sw_test
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zsh 10236 wei.shi cwd DIR 1,5 96 61411500 sw_test/sw_test2
zsh 10393 wei.shi cwd DIR 1,5 64 61413673 sw_test/sw_test2/sw_test3
-U
- List all Files used by Unix Domain Socket
$ lsof -U
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
distnoted 410 shiwei 3u unix 0xcc59970de99c3ca9 0t0 ->0xcc59970de58b4669
secd 424 shiwei 3u unix 0xcc59970de99c4091 0t0 ->0xcc59970de58b4669
UserEvent 466 shiwei 3u unix 0xcc59970de99c5cb1 0t0 ->0xcc59970de99c5d79
UserEvent 466 shiwei 4u unix 0xcc59970de99c5b21 0t0 ->0xcc59970de58b4669
UserEvent 466 shiwei 17u unix 0xcc59970de99c3a51 0t0 ->0xcc59970de99c3d71
rapportd 471 shiwei 3u unix 0xcc59970de99c3731 0t0 ->0xcc59970de58b4669
rapportd 471 shiwei 9u unix 0xcc59970df4664e41 0t0 ->0xcc59970df4662f01
rapportd 471 shiwei 11u unix 0xcc59970df4663799 0t0 ->0xcc59970df4664b21
rapportd 471 shiwei 14u unix 0xcc59970df4663091 0t0 ->0xcc59970df4663159
Sublime 473 shiwei 3u unix 0xcc59970de99c5351 0t0 /tmp/Sublime Text.4cff18d2bab96a93366319a9e0fa060d.cd247256981dd6a8c8b93b5930202e9d.sock
复合操作
列出某个用户以及某个进程所打开的文件信息
$ lsof -u [user_name] -c [process_name]
Example
$ lsof -p [PID]
如果将一个程序的
一个测试的Python 程序:
import time
print("111")
time.sleep(1)
$ python sw.py
111
...
$ sudo lsof -p 28902
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
python3.8 28902 pi 0u CHR 136,0 0t0 3 /dev/pts/0
python3.8 28902 pi 1u CHR 136,0 0t0 3 /dev/pts/0
python3.8 28902 pi 2u CHR 136,0 0t0 3 /dev/pts/0
而如果:
$ python sw.py 1> test.log
$ sudo lsof -p 29043
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
python3.8 29043 pi 0u CHR 136,0 0t0 3 /dev/pts/0
python3.8 29043 pi 1w REG 179,2 0 422722 /home/pi/Desktop/test.log
python3.8 29043 pi 2u CHR 136,0 0t0 3 /dev/pts/0
这说明 stdout 被 redict 到了 /home/pi/Desktop/test.log
。
类似地,
# 把 stdout redict
$ python sw.py 2> test.log
$ sudo lsof -p 29267
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python3.8 29267 pi 0u CHR 136,0 0t0 3 /dev/pts/0
python3.8 29267 pi 1u CHR 136,0 0t0 3 /dev/pts/0
python3.8 29267 pi 2w REG 179,2 0 422722 /home/pi/Desktop/test.log
# 把 stdout 和 stderr 都 redict
$ python sw.py > test.log 2>&1
$ sudo lsof -p 29333
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python3.8 29682 pi 0u CHR 136,0 0t0 3 /dev/pts/0
python3.8 29682 pi 1w REG 179,2 0 422722 /home/pi/Desktop/test.log
python3.8 29682 pi 2w REG 179,2 0 422722 /home/pi/Desktop/test.log
列出某个用户的所有活跃的网络端口
$ lsof -a -u test -i
Reference
- https://man7.org/linux/man-pages/man8/lsof.8.html
- https://linux.die.net/man/8/lsof
- man lsof
- https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/lsof.html
- https://en.wikipedia.org/wiki/Lsof