Linux命令 lsof


原文链接: Linux命令 lsof

lsof(list open files)是一个查看当前系统文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,该文件描述符提供了大量关于这个应用程序本身的信息。

macos

lsof -nP -iUPD
lsof -nP -iTCP
lsof -nP -i:80

关于端口的一些命令:

查看端口进程信息

lsof -i :端口号
sudo lsof -i:80

关闭某个端口的进程:

  1. 先用lsof -i:端口号 查出这个端口的进程,
  2. 找出pid,然后kill -9 pid,关闭进程

或者直接: fuser -k 80/tcp

查看端口进程:

netstat -anp | grep 80

进程相关

lsof 文件 #查看文件占用
lsof /etc/passwd //那个进程在占用/etc/passwd
lsof which httpd //那个进程在使用apache的可执行文件
lsof -p 30297 //显示那些文件被pid为30297的进程打开
lsof /dev/hda6 //那个进程在占用hda6
lsof /dev/cdrom //那个进程在占用光驱
lsof -c sendmail //查看sendmail进程的文件使用情况
lsof -c courier -u ^zahn //显示出那些文件被以courier打头的进程打开,但是并不属于用户zahn
lsof -D /tmp 显示所有在/tmp文件夹中打开的instance和文件的进程。但是symbol文件并不在列

lsof -u1000 //查看uid是100的用户的进程的文件使用情况
lsof -utony //查看用户tony的进程的文件使用情况
lsof -u^tony //查看不是用户tony的进程的文件使用情况(^是取反的意思)
lsof -i //显示所有打开的端口
lsof -i:80 //显示所有打开80端口的进程
lsof -i -U //显示所有打开的端口和UNIX domain文件
lsof -i UDP@[url]www.akadia.com:123 //显示那些进程打开了到www.akadia.com的UDP的123(ntp)端口的链接
lsof -i tcp@ohaha.ks.edu.tw:ftp -r //不断查看目前ftp连接的情况(-r,lsof会永远不断的执行,直到收到中断信号,+r,lsof会一直执行,直到没有档案被显示,缺省是15s刷新)
lsof -i tcp@ohaha.ks.edu.tw:ftp -n //lsof -n 不将IP转换为hostname,缺省是不加上-n参数

lsof /path/to/somefile:显示打开指定文件的所有进程之列表;建议配合grep使用
lsof -c string:显示其COMMAND列中包含指定字符(string)的进程所有打开的文件;可多次使用该选项
lsof -p PID:查看该进程打开了哪些文件
lsof -U:列出套接字类型的文件。一般和其他条件一起使用。如lsof -u root -a -U
lsof -u uid/name:显示指定用户的进程打开的文件;可使用脱字符"^"取反,如"lsof -u ^root"将显示非root用户打开的所有文件
lsof +d /DIR/:显示指定目录下被进程打开的文件
lsof +D /DIR/:基本功能同上,但lsof会对指定目录进行递归查找,注意这个参数要比grep版本慢
lsof -a:按"与"组合多个条件,如lsof -a -c apache -u apache
lsof -N:列出所有NFS(网络文件系统)文件
lsof -n:不反解IP至HOSTNAME
lsof -i:用以显示符合条件的进程情况
lsof -i[46] [protocol][@host][:service|port]

46:IPv4或IPv6
protocol:TCP or UDP
host:host name或ip地址,表示搜索哪台主机上的进程信息
service:服务名称(可以不只一个)
port:端口号 (可以不只一个)

lsof打开的文件可以是:

普通文件
目录
网络文件系统的文件
字符或设备文件
(函数)共享库
管道,命名管道
符号链接
网络文件(例如:NFS file、网络socket,unix域名socket)
还有其它类型的文件,等等

命令参数

-a 使所有选项是”与”的关系
-n 阻止网络号转换为域名。有助于加速lsof
-i <条件> 列出网络地址符合条件的进程。(4、6、协议、:端口、 @ip )
-c 列出COMMAND栏以指定xxx开头的文件
-p <进程号> 列出指定进程号所打开的文件
-u 列出UID号进程详情
-g 列出GID号进程详情
-d <文件号> 列出占用该文件号的进程
+d <目录> 列出目录下被打开的文件
+D <目录> 递归列出目录下被打开的文件
使用示例
无任何参数

$lsof| more
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
init 1 root cwd DIR 253,0 4096 2 /
init 1 root rtd DIR 253,0 4096 2 /
init 1 root txt REG 253,0 150352 1310795 /sbin/init
init 1 root mem REG 253,0 65928 5505054 /lib64/libnss_files-2.12.so
init 1 root mem REG 253,0 1918016 5521405 /lib64/libc-2.12.so
init 1 root mem REG 253,0 93224 5521440 /lib64/libgcc_s-4.4.6-20120305.so.1
init 1 root mem REG 253,0 47064 5521407 /lib64/librt-2.12.so
init 1 root mem REG 253,0 145720 5521406 /lib64/libpthread-2.12.so
...

COMMAND:进程的名称
PID:进程标识符
PPID:父进程标识符(需要指定-R参数)
USER:进程所有者
PGID:进程所属组

FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等:
(1)cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
(2)txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
(3)lnn:library references (AIX);
(4)er:FD information error (see NAME column);
(5)jld:jail directory (FreeBSD);
(6)ltx:shared library text (code and data);
(7)mxx :hex memory-mapped type number xx.
(8)m86:DOS Merge mapped file;
(9)mem:memory-mapped file;
(10)mmap:memory-mapped device;
(11)pd:parent directory;
(12)rtd:root directory;
(13)tr:kernel trace file (OpenBSD);
(14)v86 VP/ix mapped file;
(15)0:表示标准输入
(16)1:表示标准输出
(17)2:表示标准错误
初始打开每个应用程序时,都具有3个文件描述符,从0到2,分别表示标准输入、输出和错误流。因此,大多数应用程序所打开的FD都是从3开始
一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等
(1)u:表示该文件被打开并处于读取/写入模式
(2)r:表示该文件被打开并处于只读模式
(3)w:表示该文件被打开并处于只写模式
(4)空格:表示该文件的状态模式为unknow,且没有锁定
(5)-:表示该文件的状态模式为unknow,且被锁定
同时在文件状态模式后面,还跟着相关的锁
(1)N:for a Solaris NFS lock of unknown type;
(2)r:for read lock on part of the file;
(3)R:for a read lock on the entire file;
(4)w:for a write lock on part of the file;(文件的部分写锁)
(5)W:for a write lock on the entire file;(整个文件的写锁)
(6)u:for a read and write lock of any length;
(7)U:for a lock of unknown type;
(8)x:for an SCO OpenServer Xenix lock on part of the file;
(9)X:for an SCO OpenServer Xenix lock on the entire file;
(10)space:if there is no lock.

TYPE:文件类型,如DIR、REG等,常见的文件类型:
(1)DIR:表示目录
(2)CHR:表示字符类型
(3)BLK:块设备类型
(4)UNIX: UNIX 域套接字
(5)FIFO:先进先出 (FIFO) 队列
(6)IPv4:网际协议 (IP) 套接字
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称

列出COMMAND以XXX开头的文件

lsof -c mysql

列出某进程打开的文件

lsof -p 1234

列出网络连接相关文件

#列出所有网络连接
lsof -i
#列出所有tcp网络连接相关文件(以网络地址显示)
lsof -ni tcp
#列出所有端口3306相关文件(以网络地址显示)
lsof -ni :3306
#列出所有ipv6相关的文件
lsof -ni 6
#列出所有进程1234打开的所有ipv4 文件,并3秒刷新一次(注意使用-a 表示and)
lsof -p 1234 -a -ni 4 -r 3

恢复rm删除的文件

系统中某个文件被意外删除,只要此时系统中某个进程正在访问这个文件,那么可以通过lsof从/proc目录下恢复文件

假设 /var/log/messages被删除
使用lsof |grep /var/log/messages
rsyslogd 5925 root 1w REG 8,2 4369 266184 /var/log/messages (deleted)
从上面的信息可以看到PID 5925(syslogd)打开文件的文件描述符为1,同时发现/var/log/messages已经被删除了。
最后通过重定向的方法恢复被删除的/var/log/messages
cat /pro/5925/fd/1 >/var/log/messages

`