lsof详解
- -a :列出找开文件存在的进程,如果有两个条件,两个条件必须同时满足
- -c <进程名(pid|pid_name)>:列出指定进程所打开的文件
- -g :列出GID号进程详情
- -d <文件>:列出占用该文件号的进程
- +d <目录>:列出目录下被打开的文件
- +D <目录>:递归列出目录下被找开的文件
- -n <目录>:列出使用NFS的文件
- -i <条件>:列出符合条件的进程。(ipv4,ipv6,TCP,UDP,:port,@ip[:port])
- COMMAND : 进程的名称
- PID : 进程号
- USER : 进程所有者
- FD : 文件描述符
- cwd(current work dirctory),即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
- txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的/sbin/init
- 0:表示标准输入
- 1:表示标准输出
- 2:表示标准错误
- u:表示该文件被打开并处于读取/写入模式
- r:表示该文件被打开并处于只读模式
- w:表示该文件被找开并处于只写模式
- 空格:表示该文件的状态模式为unknow,且没有锁定
- -:表示该文件的状态模式为unknow,且被锁定
- TYPE : 文件类型:
- REG:文件
- DIR:目录
- CHR:字符类型
- BLK:块设备
- UNIX:UNIX域套接字
- FIFO:先进先出队列
- IPV4:
- DEVICE : 指定磁盘名称
- SIZE : 文件大小
- NODE : 索引节点
- NAME : 打开文件的确切名称
lsof(list open files)命令用于查看你进程打开的主文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户执行。
在linux环境下,任何事物都以文件形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议TCP和用户数据报协议UDP套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。
语法
lsof [option] [/path/to/somefile]
选项:
显示示例:
[root@localhost ~]# lsof | less
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
init 1 root cwd DIR 8,2 4096 2 /
init 1 root rtd DIR 8,2 4096 2 /
init 1 root txt REG 8,2 150352 654143 /sbin/init
init 1 root mem REG 8,2 66432 392482 /lib64/libnss_files-2.12.so
init 1 root mem REG 8,2 1930416 404125 /lib64/libc-2.12.so
init 1 root mem REG 8,2 93320 404134 /lib64/libgcc_s-4.4.7-20120601.so.1
init 1 root mem REG 8,2 47760 404128 /lib64/librt-2.12.so
init 1 root mem REG 8,2 146592 404127 /lib64/libpthread-2.12.so
init 1 root mem REG 8,2 268232 404144 /lib64/libdbus-1.so.3.4.0
init 1 root mem REG 8,2 39896 392622 /lib64/libnih-dbus.so.1.0.0
init 1 root mem REG 8,2 101920 392624 /lib64/libnih.so.1.0.0
init 1 root mem REG 8,2 161704 404124 /lib64/ld-2.12.so
init 1 root 0u CHR 1,3 0t0 4601 /dev/null
init 1 root 1u CHR 1,3 0t0 4601 /dev/null
init 1 root 2u CHR 1,3 0t0 4601 /dev/null
init 1 root 3r FIFO 0,8 0t0 10138 pipe
init 1 root 4w FIFO 0,8 0t0 10138 pipe
init 1 root 5r DIR 0,10 0 1 inotify
init 1 root 6r DIR 0,10 0 1 inotify
...
lsof输出各列信息的意义如下:
数值表示应用程序的文件描述符,这是打开文件时返回的一个整数,一般在标准输出、标准输入、标准错误后还跟着文件状态模式
常用示例:
lsof `which nginx` //哪个进程在使用nginx的可执行文件
lsof /usr/sbin/sshd //哪个进程在占用/usr/sbin/sshd
lsof -c nginx //查看nginx进程的文件使用情况
lsof -c nginx -u ^root //显示出那些文件被以nginx打头,但是并不属于用户root
lsof -p 1 //显示哪些文件被pid为1的进程打开
lsof -u`id -u mysql` //查看用户mysql的进程的文件使用情况
lsof -i //显示所有打开的端口
lsof -i:80 //显示所有打开80端口的进程
lsof -iTCP@www.ccc.com //显示哪些进程打开到www.ccc.com的连接
lsof +d /dir/ //显示目录下被进程打开的文件
lsof +D /dir/ //同上,但是会搜索目录下的所有目录,时间相对较长
lsof -n //不将IP地址转换为hostname,缺省是不加上-n参数
恢复删除的文件:
当Linux计算机受到入侵时,常见的情况是日志文件被删除,以掩盖攻击者的踪迹。管理错误也可能导致意外删除重要的文件,比如在清理旧日志时,意外地删除了数据库的活动事务日志。有时可以通过lsof来恢复这些文件。
当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。
在/proc 目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这 些文件进行读取和写入时,实际上是在从内存中获取相关信息。大多数与 lsof 相关的信息都存储于以进程的 PID 命名的目录中,即 /proc/1234 中包含的是 PID 为 1234 的进程的信息。每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信 息。lsof 程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。
当系统中的某个文件被意外地删除 了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过lsof从/proc目录下恢复该文件的内容。 假如由于误操作将/var/log/secure文件删除掉了,那么这时要将/var/log/secure文件恢复的方法如下:
首先使用lsof来查看当前是否有进程打开/var/log/secure,如下:
# lsof +D /var/log/ //我是用这个命令先来查看这个目录下哪些个日志当前正在内存中,然后在做实验的^~^
# lsof | grep /var/log/secure
rsyslogd 1200 root 4w REG 8,3 1907 2100236 /var/log/secure(deleted)
从上面的信息可以看到PID 1200(rsyslogd) 打开的文件描述符为4,同时还可以看到/var/log/secure已经被删除了。因此我们可以在/proc/1200/fd/4(fd下的每个以数字命名的文件表示进程对应的文件描述符)中就有相应的信息。
# cat /proc/1200/fd/4 > /var/log/secure //这就完成了恢复工作
对于许多应用程序,尤其是日志文件和数据库(只有ibd文件可恢复,.frm是没被进程执行的),这种恢复删除文件的方法非常有用。