在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能
[@zw_74_196 classes]# lsof |more
COMMAND PID USER FD TYPE DEVICE SIZE 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 43496 426056 /sbin/init
init 1 root mem REG 8,1 139504 655364 /lib64/ld-2.5.so
init 1 root mem REG 8,1 1722304 655371 /lib64/libc-2.5.so
init 1 root mem REG 8,1 23360 655413 /lib64/libdl-2.5.so
init 1 root mem REG 8,1 95464 655694 /lib64/libselinux.so.1
init 1 root mem REG 8,1 247496 655362 /lib64/libsepol.so.1
init 1 root 10u FIFO 0,17 2347 /dev/initctl
COMMAND:进程的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
TYPE:文件类型,如DIR、REG等
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
file_type宏定义 说明
1 EXT2_FT_REG_FILE 普通文件
2 EXT2_FT_DIR 目录
3 EXT2_FT_CHRDEV 字符设备
4 EXT2_FT_BLKDEV 块设备
5 EXT2_FT_FIFO 命名管道
6 EXT2_FT_SOCK socket
7 EXT2_FT_SYMLINK 符号链接
常用的参数列表:
lsof filename 显示打开指定文件的所有进程
lsof -a 表示两个参数都必须满足时才显示结果
lsof -c string 显示COMMAND列中包含指定字符的进程所有打开的文件
lsof -u username 显示所属user进程打开的文件
lsof -g gid 显示归属gid的进程情况
lsof +d /DIR/ 显示目录下被进程打开的文件
lsof +D /DIR/ 同上,但是会搜索目录下的所有目录,时间相对较长
lsof -d FD 显示指定文件描述符的进程
lsof -n 不将IP转换为hostname,缺省是不加上-n参数
lsof -i 用以显示符合条件的进程情况
lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
46 --> IPv4 or IPv6
protocol --> TCP or UDP
hostname --> Internet host name
hostaddr --> IPv4地址
service --> /etc/service中的 service name (可以不只一个)
port --> 端口号 (可以不只一个)
例如: 查看22端口现在运行的情况
#lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
sshd 17385 root 3u IPv4 4440588 TCP *:ssh (LISTEN)
sshd 23604 root 3u IPv4 4487485 TCP tc_154_37:ssh->192.168.97.88:28638 (ESTABLISHED)
sshd 23997 root 3u IPv4 4489792 TCP tc_154_37:ssh->10.6.48.129:simp-all (ESTABLISHED)
sshd 24001 wgadmin 3u IPv4 4489792 TCP tc_154_37:ssh->10.6.48.129:simp-all (ESTABLISHED)
sshd 26798 root 3u IPv4 4508451 TCP tc_154_37:ssh->192.168.97.88:40071 (ESTABLISHED)
查看所属root用户进程所打开的文件类型为txt的文件
#lsof -a -u root -d txt
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 23608 root txt REG 8,1 729900 721006 /bin/bash
snmpd 23698 root txt REG 8,5 29960 768356 /usr/sbin/snmpd
sshd 23997 root txt REG 8,5 409024 768336 /usr/sbin/sshd
rotatelog 25658 root txt REG 8,5 5964 553490 /usr/local/apache/bin/rotatelogs
sshd 26798 root txt REG 8,5 409024 768336 /usr/sbin/sshd
bash 26802 root txt REG 8,1 729900 721006 /bin/bash
lsof 27004 root txt REG 8,5 121364 768404 /usr/sbin/lsof
lsof 27005 root txt REG 8,5 121364 768404 /usr/sbin/lsof
实际应用:
一、查找谁在使用文件系统
在卸载文件系统时,如果该文件系统中有任何打开的文件,操作通常将会失败。那么通过lsof可以找出那些进程在使用当前要卸载的文件系统,如下:
#lsof /usr/local/nginx/sbin/nginx
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 29777 root cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30146 root cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30147 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30148 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30149 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30150 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30151 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30152 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30153 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
nginx 30154 nobody cwd DIR 8,5 4096 360587 /usr/local/nginx/sbin/
二、恢复删除的文件
当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过lsof从/proc目录下恢复该文件的内容。 假如由于误操作将logs/error.log文件删除掉了,那么这时要logs/error.log将文件恢复的方法如下:
#lsof |grep error.log
nginx 30146 root 2w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30146 root 4w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30147 nobody 2w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30147 nobody 4w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30148 nobody 2w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30148 nobody 4w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30149 nobody 2w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30149 nobody 4w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
nginx 30150 nobody 2w REG 8,5 15463 363592 /usr/local/nginx/logs/error.log (delete)
从上面的信息可以看到 PID 30146 打开文件的文件描述符为 2。同时还可以看到/usr/local/nginx/logs/error.log已经标记被删除了。因此我们可以在 /proc/30146/fd/2 (fd下的每个以数字命名的文件表示进程对应的文件描述符)中查看相应的信息,如下
#more /proc/30146/fd/2
2011/10/09 10:34:51 [emerg] 10662#0: getpwnam("www") failed
2011/10/09 10:54:41 [emerg] 10884#0: unknown directive "proxy_cache_purge" in /usr/local/nginx/conf/nginx.conf:256
2011/10/09 10:55:02 [emerg] 10926#0: open() "/usr/local/nginx/../conf/nginx.conf" failed (2: No such file or directory)
2011/10/09 10:55:24 [emerg] 10956#0: unknown directive "proxy_cache_purge" in /usr/local/nginx/conf/nginx.conf:256
2011/10/09 10:56:25 [emerg] 10981#0: unknown directive "proxy_cache_purge" in /usr/local/nginx/conf/nginx.conf:256
2011/10/09 11:07:41 [emerg] 23557#0: mkdir() "/opt/temp/nginx_temp_path" failed (2: No such file or directory)
2011/10/09 11:08:54 [emerg] 23582#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
2011/10/09 11:08:54 [emerg] 23582#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
这个文件中得内容与error.log日志中的内容是相同的,所以用这个文件就可以恢复意外被删除的error.log