Linux系统诊断必备技能之一:lsof 用法详解!

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

一、命令参数

-a:列出打开文件存在的进程;
-c<进程名>:列出指定进程所打开的文件;
-g:列出GID号进程详情;
-d<文件号>:列出占用该文件号的进程;
+d<目录>:列出目录下被打开的文件;
+D<目录>:递归列出目录下被打开的文件;
-n<目录>:列出使用NFS的文件;
-i<条件>:列出符合条件的进程(4、6、协议、:端口、 @ip );
-p<进程号>:列出指定进程号所打开的文件;
-u:列出UID号进程详情;
-h:显示帮助信息;
-v:显示版本信息。

二、实例讲解  

 1、lsof输出各列信息的意义,如下:

COMMAND:进程的名称;
PID:进程标识符;
PPID:父进程标识符(需要指定-R参数);
USER:进程所有者;
PGID:进程所属组;
FD:文件描述符,应用程序通过文件描述符识别该文件。

2、文件描述符列表: 

①. cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改;
②. txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库;
③. lnn:library references (AIX);
④. er:FD information error (see NAME column);
⑤. jld:jail directory (FreeBSD);
⑥. ltx:shared library text (code and data);
⑦. mxx :hex memory-mapped type number xx.
⑧. m86:DOS Merge mapped file;
⑨. mem:memory-mapped file;
⑩. mmap:memory-mapped device;
⑪. pd:parent directory;
⑫. rtd:root directory;
⑬. tr:kernel trace file (OpenBSD);
⑭. v86 VP/ix mapped file;
⑮. 0:表示标准输出;
⑯. 1:表示标准输入;
⑰. 2:表示标准错误。

3、一般在标准输出、标准错误、标准输入后,还跟着文件状态模式:  

①.u:表示该文件被打开并处于读取/写入模式;
②.r:表示该文件被打开并处于只读模式;
③.w:表示该文件被打开并处于只写模式;
④.空格:表示该文件的状态模式为unknow,且没有锁定;
⑤.-:表示该文件的状态模式为unknow,且被锁定。

4、同时在文件状态模式后面,还跟着相关的锁: 

①. 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。

5、文件类型  

①. DIR:表示目录;
②. CHR:表示字符类型;
③. BLK:块设备类型;
④. UNIX:UNIX 域套接字;
⑤. FIFO:先进先出 (FIFO) 队列;
⑥. IPv4:网际协议 (IP) 套接字;
⑦. DEVICE:指定磁盘的名称;
⑧. SIZE:文件的大小;
⑨. NODE:索引节点(文件在磁盘上的标识);
⑩. NAME:打开文件的确切名称。

三、可打开文件  

①. 普通文件;
②. 目录;
③. 网络文件系统的文件;
④. 字符或设备文件;
⑤. (函数)共享库;
⑥. 管道,命名管道;
⑦. 符号链接;
⑧. 网络文件(例如:NFS file、网络socket,unix域名socket);
⑨. 其它类型的文件等。

四、常规用法

lsof 常被用来查找应用程序打开的文件名称和数目,系统管理员可能想尝试找出某个特定应用程序将日志数据记录到何处,或者正在跟踪某个问题。接下来,我们来看看是如何操作的:

1、进程篇

(1).查看由登陆用户启动而非系统启动的进程:

命令: lsof /dev/pts/*                      //* 表示进程号码 

a. /dev/pts是远程登陆(telnet,ssh等)后创建的控制台设备文件所在的目录;
b. 第一个用户登陆,console的设备文件为/dev/pts/0,第二个为/dev/pts/1,以此类推;
c. 通过查看/dev/pts下的进程,我们将可以了解到由登陆用户启动而非系统启动的进程有哪些。

(2).查看文件,设备被哪些进程占用:

 命令:lsof /dev/tty1

a. /dev/tty就是当前进程的控制终端的设备特殊文件;
b. 通过查看/dev/tty下文件可以知道文件、设备的进程占用情况。

(3).指定进程号,可以查看该进程打开的文件: 

 命令:lsof -p 24398

a. 通过加入参数-p,我们可以指定一个PID,然后查看该进程下打开的文件。
b. 本例我们查看的是nginx下打开的相关文件。

2、文件篇

(1).查看指定程序打开的文件

 命令:lsof -c sshd

a.通过参数-c可以列出指定进程所打开的文件情况,以上是我们打开sshd下被打开文件的情况。

(2).查看指定用户打开的文件

 命令:lsof -u root | more

a.通过参数-u查看root用户下存在的文件情况,由于root下显示内容较多,可以利用more来限制,进行分页查看。

(3).查看指定目录下被打开的文件

命令:lsof +D /home/ 或lsof +d /home/

3、网络篇

(1).查看所有网络连接

 命令:lsof -i 和 lsof -i@127.0.0.1

a.通过参数 -i 查看网络连接的情况,包括连接的ip、端口等;以及一些服务的连接情况,例如:sshd等。也可以通过指定ip查看该ip的网络连接情况。

(2)、查看端口连接情况

 命令:lsof -i :22

a.通过参数-i:端口可以查看端口的占用情况,-i参数还有查看协议,ip的连接情况等。 

 4、综合篇

(1).查看指定进程打开的网络连接

 命令:lsof -i -a -p 1535

a.使用了参数-i、-a、-p等,-i查看网络连接情况,-a查看存在的进程,-p指定进程。

(2).查看指定状态的网络连接

 命令:lsof -n -P -i TCP -s TCP:ESTABLISHED

a.参数解释: -n:no host names, -P:no port names,-i TCP指定协议,-s指定协议状态;通过多个参数我们可以清晰的查看网络连接情况、协议连接情况等。

 五、恢复被删除的日志

 Linux的系统日志默认保存在/var/log下

当Linux系统被入侵后,很多入侵者经常会删除系统中的各种日志,包括Web的access和error日志、last日志、messages日志、secure日志等,阻碍应急响应和取证调查,比如rm -rf /var/log。

遇到这种情况,不要关闭或者重启服务器系统,也不要关闭或重启相关服务或者进程,如:恢复apache的访问日志/var/log/httpd/access_log时,不能关闭或者重启服务器系统,也不能重启httpd服务。

 1、假设我们要恢复被删除的messages日志和secure日志:

 a.首先通过losf命令找到使用messages文件的进程的PID和messages文件的FD(文件描述符):

[root@localhost log]# lsof |grep /var/log/messages
rsyslogd   1291      root    1w      REG              202,2      148    2885609 /var/log/messages (deleted)

从上面命令输出可以看到,这个打开/var/log/messages文件的进程的PID是1291,文件/var/log/messages的FD(文件描述符)是1,状态为deleted,标记被删除,但其实该文件并没有从磁盘中删除。  

 b.如果删除的文件还存在操作的进程,数据将可能被找回,可以在/proc/815/fd/4找到被删除的/var/log/messages文件;

[root@localhost log]# rm -rf /var/log/
[root@localhost log]# ll /var/log/
ls: cannot access /var/log/: No such file or directory
[root@localhost log]# lsof |grep /var/log/messages
rsyslogd   1291      root    1w      REG              202,2      148    2885609 /var/log/messages (deleted)
[root@localhost log]# wc -l /proc/1291/fd/1
1 /proc/1291/fd/1
[root@localhost log]# head -n 1 /proc/1291/fd/1
Mar 24 03:49:01 localhost rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="1291" x-info="http://www.rsyslog.com"] rsyslogd was HUPed
[root@localhost log]# mkdir -p /var/log
[root@localhost log]# touch /var/log/messages
[root@localhost log]# cat /proc/1291/fd/1 > /var/log/messages 
[root@localhost log]# cat /var/log/messages
Mar 24 03:49:01 localhost rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="1291" x-info="http://www.rsyslog.com"] rsyslogd was HUPed

在Linux系统中删除了一个文件,只要进程还在对文件进行操作,就可能还存在一个inode的引用:/proc/进程号/fd/文件描述符,只要知道当前打开文件的进程pid和文件描述符fd,即可利用lsof命令还原出被删除的文件。

六、总 结

Linux大量使用了文件,作为系统管理员,lsof 允许用户对核心内存进行查看,以找出系统当前如何使用这些文件。lsof的简单用法可以告诉用户哪些进程打开了哪些文件,以及哪些文件由哪些进程打开。

---------------------------------------------书山有路勤为径,学海无涯苦作舟--------------------------------------------------------

原文地址:https://www.cnblogs.com/easonscx/p/10598964.html