简介
lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。
$ lsof (选项)
选项
描述
-a
列出打开文件存在的进程;
-c<进程名>
列出指定进程所打开的文件;
-g
列出GID号进程详情;
-d<文件号>
列出占用该文件号的进程;
+d<目录>
列出目录下被打开的文件;
+D<目录>
递归列出目录下被打开的文件;
-n<目录>
列出使用NFS的文件;
-i<条件>
列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>
列出指定进程号所打开的文件;
-u
列出UID号进程详情;
-h
显示帮助信息;
-v
显示版本信息。
在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。
$ lsof
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
init 1 root cwd DIR 8,1 4096 2 /
init 1 root rtd DIR 8,1 4096 2 /
init 1 root txt REG 8,1 150584 654127 /sbin/init
udevd 415 root 0u CHR 1,3 0t0 6254 /dev/null
udevd 415 root 1u CHR 1,3 0t0 6254 /dev/null
udevd 415 root 2u CHR 1,3 0t0 6254 /dev/null
udevd 690 root mem REG 8,1 51736 302589 /lib/x86_64-linux-gnu/libnss_files-2.13.so
syslogd 1246 syslog 2w REG 8,1 10187 245418 /var/log/auth.log
syslogd 1246 syslog 3w REG 8,1 10118 245342 /var/log/syslog
dd 1271 root 0r REG 0,3 0 4026532038 /proc/kmsg
dd 1271 root 1w FIFO 0,15 0t0 409 /run/klogd/kmsg
dd 1271 root 2u CHR 1,3 0t0 6254 /dev/null
COMMAND:进程的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等 TYPE:文件类型,如DIR、REG等
TYOE:文件类型
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
N:for a Solaris NFS lock of unknown type(对于未知类型的Solaris NFS锁);
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(对于文件的sco openserver xenix锁);
X:for an SCO OpenServer Xenix lock on the entire file(对于整个文件的sco openserver xenix锁);
space:if there is no lock(如果没有锁).
#列出所有打开的文件:
lsof
备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位
lsof /filepath/file
#递归查看某个目录的文件信息
lsof +D /filepath/filepath2/
备注: 使用了+D,对应目录下的所有子目录和文件都会被列出
lsof | grep ‘/filepath/filepath2/’
lsof -u username
备注: -u 选项,u其实是user的缩写
lsof -c mysql
备注: -c 选项将会列出所有以mysql开头的程序的文件,其实你也可以写成lsof | grep mysql,但是第一种方法明显比第二种方法要少打几个字符了
lsof -c mysql -c apache
lsof -u test -c mysql
lsof -u ^root
备注:^这个符号在用户名之前,将会把是root用户打开的进程不让显示
lsof -p 1
lsof -p 123,456,789
lsof -p ^1
lsof -i
lsof -i tcp
lsof -i udp
lsof -i :3306
lsof -i udp:55
lsof -i tcp:80
lsof -a -u test -i
lsof -N
#域名socket文件
lsof -u
#某个用户组所打开的文件信息
lsof -g 5555
lsof -d description(like 2)
lsof -d 2-3
usage: [-?abhlnNoOPRtUvV] [+|-c c] [+|-d s] [+D D] [+|-f[cgG]]
[-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]
理解一些关于lsof如何工作的关键性东西是很重要的。最重要的是,当你给它传递选项时,默认行为是对结果进行“或”运算。因此,如果你正是用-i来拉出一个端口列表,同时又用-p来拉出一个进程列表,那么默认情况下你会获得两者的结果。
下面的一些其它东西需要牢记:
默认 : 没有选项,lsof列出活跃进程的所有打开文件
组合 : 可以将选项组合到一起,如-abc,但要当心哪些选项需要参数
-a : 结果进行“与”运算(而不是“或”)
-l : 在输出显示用户ID而不是用户名
-h : 获得帮助
-t : 仅获取进程ID
-U : 获取UNIX套接口地址
-F : 格式化输出结果,用于其它命令。可以通过多种方式格式化,如-F pcfn(用于进程id、命令名、文件描述符、文件名,并以空终止)
有些人喜欢用netstat来获取网络连接,但是我更喜欢使用lsof来进行此项工作。结果以对我来说很直观的方式呈现,我仅仅只需改变我的语法,就可以通过同样的命令来获取更多信息。
语法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
1. $ lsof -i
2. COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
3. dhcpcd 6061 root 4u IPv4 4510 UDP *:bootpc
4. sshd 7703 root 3u IPv6 6499 TCP *:ssh (LISTEN)
5. sshd 7892 root 3u IPv6 6757 TCP 10.10.1.5:ssh->192.168.1.5:49901 (ESTABLISHED)
$ lsof -i 6
$ lsof -iTCP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rapportd 249 alon 3u IPv4 0xbf4f51b061be171d 0t0 TCP *:62740 (LISTEN)
rapportd 249 alon 4u IPv6 0xbf4f51b0709f2fdd 0t0 TCP *:62740 (LISTEN)
rapportd 249 alon 10u IPv4 0xbf4f51b06aaa1d9d 0t0 TCP alon-mbp:62740->alon:51824 (ESTABLISHED)
或者,你也可以通过端口搜索,这对于要找出什么阻止了另外一个应用绑定到指定端口实在是太棒了。
$ lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 442 alon 7u IPv4 0xbf4f51b06b5f071d 0t0 TCP *:http-alt (LISTEN)
nginx 474 alon 7u IPv4 0xbf4f51b06b5f071d 0t0 TCP *:http-alt (LISTEN)
这对于你在检查是否开放连接到网络中或互联网上某个指定主机的连接时十分有用。
$ lsof -i@192.168.1.3 //ssh服务器地址
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 13971 alon 3u IPv4 0xbf4f51b065af171d 0t0 TCP alon-mbp:63001->redminote5a-hongmish:ssh (ESTABLISHED)
你也可以组合主机与端口的显示信息。
$ lsof -i@192.168.1.3:22 //ssh服务器地址
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 13971 alon 3u IPv4 0xbf4f51b065af171d 0t0 TCP alon-mbp:63001->redminote5a-hongmish:ssh (ESTABLISHED)
找出正等候连接的端口。
$ lsof -i -sTCP:LISTEN
你也可以grep “LISTEN”来完成该任务。
$ lsof -i | grep -i LISTEN
iTunes 400 daniel 16u IPv4 0x4575228 0t0 TCP *:daap (LISTEN)
你也可以显示任何已经连接的连接。
$ lsof -i -sTCP:ESTABLISHED
你也可以通过grep搜索“ESTABLISHED”来完成该任务。
$ lsof -i | grep -i ESTABLISHED
firefox-b 169 daniel 49u IPv4 0t0 TCP 1.2.3.3:1863->1.2.3.4:http (ESTABLISHED)
你也可以获取各种用户的信息,以及它们在系统上正干着的事情,包括它们的网络活动、对文件的操作等。
$ lsof -u alon
Dock 258 alon cwd DIR 1,4 960 2 /
Dock 258 alon txt REG 1,4 5468560 12885166254 /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock
Dock 258 alon txt REG 1,4 65556 12892552336 /Library/Caches/com.apple.iconservices.store/822428C4-1B74-4D07-3A23-9F4D9799678E.isdata
Dock 258 alon txt REG 1,4 21104 12895185769 /Library/Preferences/Logging/.plist-cache.BdSX1osv
Dock 258 alon txt REG 1,4 27154336 12885622695 /usr/share/icu/icudt62l.dat
Dock 258 alon txt REG 1,4 239648 12887956801 /private/var/db/timezone/tz/2019c.1.0/icutz/icutz44l.dat
Dock 258 alon txt REG 1,4 21960 12894991454 /Library/Application Support/CrashReporter/SubmitDiagInfo.domains
Dock 258 alon txt REG 1,4 4116 12892587129 /Library/Caches/com.apple.iconservices.store/54ADF811-CE68-A6FB-3ADC-D61EF5134EEB.isdata
$ lsof -u ^alon
Dock 258 root cwd DIR 1,4 960 2 /
Dock 258 root txt REG 1,4 5468560 12885166254 /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock
可以消灭指定用户运行的所有东西,这真不错。
$ kill -9 `lsof -t -u daniel`
可以查看指定程序或进程由什么启动,这通常会很有用,而你可以使用lsof通过名称或进程ID过滤来完成这个任务。下面列出了一些选项:
$ lsof -c syslog-ng
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
syslog-ng 7547 root cwd DIR 3,3 4096 2 /
syslog-ng 7547 root rtd DIR 3,3 4096 2 /
syslog-ng 7547 root txt REG 3,3 113524 1064970 /usr/sbin/syslog-ng
-- snipped --
$ lsof -p 10075
3. -- snipped --
4. sshd 10068 root mem REG 3,3 34808 850407 /lib/libnss_files-2.4.so
5. sshd 10068 root mem REG 3,3 34924 850409 /lib/libnss_nis-2.4.so
6. sshd 10068 root mem REG 3,3 26596 850405 /lib/libnss_compat-2.4.so
7. sshd 10068 root mem REG 3,3 200152 509940 /usr/lib/libssl.so.0.9.7
8. sshd 10068 root mem REG 3,3 46216 510014 /usr/lib/liblber-2.3
9. sshd 10068 root mem REG 3,3 59868 850413 /lib/libresolv-2.4.so
10. sshd 10068 root mem REG 3,3 1197180 850396 /lib/libc-2.4.so
11. sshd 10068 root mem REG 3,3 22168 850398 /lib/libcrypt-2.4.so
12. sshd 10068 root mem REG 3,3 72784 850404 /lib/libnsl-2.4.so
13. sshd 10068 root mem REG 3,3 70632 850417 /lib/libz.so.1.2.3
14. sshd 10068 root mem REG 3,3 9992 850416 /lib/libutil-2.4.so
15. -- snipped --
$ lsof -t -c Mail
350
通过查看指定文件或目录,你可以看到系统上所有正与其交互的资源——包括用户、进程等。
$ lsof /var/log/messages/
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
syslog-ng 7547 root 4w REG 3,3 217309 834024 /var/log/messages
$ lsof /home/daniel/firewall_whitelist.txt
与tcpdump类似,当你开始组合查询时,它就显示了它强大的功能。
$ lsof -u daniel -i @1.1.1.1
bkdr 1893 daniel 3u IPv6 3456 TCP 10.10.1.10:1234->1.1.1.1:31337 (ESTABLISHED)
$ kill -HUP `lsof -t -c sshd`
这通常(当不总是)表示某个攻击者正尝试通过删除文件入口来隐藏文件内容。
$ lsof +L1
(hopefully nothing)
$ lsof -i @fw.google.com:2150=2180
手机扫一扫
移动阅读更方便
你可能感兴趣的文章