lsof命令详解程序员

lsof命令

      用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户执行。

      在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。

输出信息的含义

在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。

直接输入lsof:

lsof命令详解程序员

COMMAND:进程的名称 PID:进程标识符

USER:进程所有者

FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等 TYPE:文件类型,如DIR、REG等

DEVICE:指定磁盘的名称

SIZE:文件的大小

NODE:索引节点(文件在磁盘上的标识)

NAME:打开文件的确切名称

FD 列中的文件描述符cwd 值表示应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改,txt 类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序。

其次数值表示应用程序的文件描述符,这是打开该文件时返回的一个整数。如上的最后一行文件/dev/initctl,其文件描述符为 10。u 表示该文件被打开并处于读取/写入模式,而不是只读 ® 或只写 (w) 模式。同时还有大写 的W 表示该应用程序具有对整个文件的写锁。该文件描述符用于确保每次只能打开一个应用程序实例。初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 FD 都是从 3 开始。

与 FD 列相比,Type 列则比较直观。文件和目录分别称为 REG 和 DIR。而CHR 和 BLK,分别表示字符和块设备;或者 UNIX、FIFO 和 IPv4,分别表示 UNIX 域套接字、先进先出 (FIFO) 队列和网际协议 (IP) 套接字。

常用命令及用法

-p 选项,列出pid所打开的文件 
# sudo lsof -p 32463   //展示进程号32463所打开的文件情况, 如果要多个,则用逗号隔开 
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF       NODE NAME 
java    32463 root  cwd    DIR                8,8     4096    2121777 /www/data/tomcat/bin 
-u 选项, 列出某个用户打开的文件 
#lsof -u wang 
COMMAND  PID USER   FD      TYPE             DEVICE SIZE/OFF      NODE NAME 
sshd    2104  wang  cwd   unknown                                       /proc/2104/cwd (readlink: Permission denied) 
sshd    2104  wang  rtd   unknown                                       /proc/2104/root (readlink: Permission denied) 
-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 --> 端口号 (可以不止一个) 
#sudo lsof -i 4   //IpV4网络文件的打开情况 
#sudo lsof -n -i [email protected]:30085   //展示TCP连接192.168.20.31:30085的连接情况 
COMMAND    PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME 
redis-ser 6418 root 3231u  IPv4 871410697      0t0  TCP 192.168.20.30:6380->192.168.20.31:30085 (ESTABLISHED) 
#sudo lsof -i @192.168.20.31  //查看与192.168.20.31连接的情况  
COMMAND    PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
java      1818 root  387u  IPv4  884293373      0t0  TCP wang_zk1:wang.com:30471 (ESTABLISHED) 
java      1818 root  388u  IPv4  884293374      0t0  TCP wang_zk1:wang.com:30469 (ESTABLISHED) 
#sudo lsof -i @192.168.20.31:30471  //查看与192.168.20.31的30471端口的文件打开情况 
COMMAND  PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME 
java    1818 root  387u  IPv4 884293373      0t0  TCP wang_zk1:wang.com:30471 (ESTABLISHED) 
#sudo lsof -i:1883  查看1883端口的 
COMMAND  PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME 
java    8743 root   49u  IPv4 771370268      0t0  TCP *:1883 (LISTEN) 
#sudo lsof -i:1883,1885   //可以查看1883,1885端口使用情况 
COMMAND   PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME 
java     8743 root   49u  IPv4 771370268      0t0  TCP *:1883 (LISTEN) 
main    16184 root   13u  IPv4 225274829      0t0  TCP localhost:w1884 (LISTEN) 
#sudo lsof -i TCP:80   //打开TCP 80端口 
COMMAND   PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
nginx    5604  www   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
nginx    5605  www   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
#sudo lsof -T s -i UDP   //显示UDP端口的状况 
COMMAND     PID   USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
memcached  7777 nobody   27u  IPv4  140461247      0t0  UDP wang_zk1:22622 
#sudo lsof -i   //显示所有internet 
memcached 12659 nobody   41u  IPv4  771440826      0t0  TCP wang_zk1:memcache->wang_zk1:16054 (ESTABLISHED) 
memcached 12659 nobody   42u  IPv4  771248651      0t0  TCP wang_zk1:memcache->wang_zk1:46769 (ESTABLISHED) 
memcached 12659 nobody   43u  IPv4  771379102      0t0  TCP wang_zk1:memcache->wang_zk1:10402 (ESTABLISHED) 
memcached 12659 nobody   44u  IPv4 3907515697      0t0  TCP wang_zk1:memcache->wang_zk1:56351 (ESTABLISHED) 
#sudo lsof  -i :80 
COMMAND   PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
nginx    5604  www   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
nginx    5605  www   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
nginx    5606  www   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
#sudo lsof -n -i [email protected]    //展示与192.168.20.31的连接情况,并直接展示ip出来 
redis-ser 6418 root 3231u  IPv4  871410697      0t0  TCP 192.168.20.30:6380->192.168.20.31:30085 (ESTABLISHED) 
#sudo lsof -n -i :80     //-n 表示阻止把主机ip转换为主机名 
COMMAND   PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
java    32463 root   51u  IPv4 3511973379      0t0  TCP 192.168.20.30:25285->192.168.7.141:http (CLOSE_WAIT) 
java    32463 root   53u  IPv4 3511079896      0t0  TCP 192.168.20.30:35451->192.168.7.141:http (CLOSE_WAIT) 
-c 选项 
#sudo lsof -c java   显示command列中以java的所有打开的文件 
#sudo lsof -c java -c sh  显示command列中以java开头或以sh开头的打开的文件 
#sudo lsof -c ^java   显示command列中所有不以java开头的打开的文件 
-s 选项,选择TCP,UDP的连接状况 
#sudo lsof -iTCP -sTCP:LISTEN 
COMMAND     PID   USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
zabbix_ag   632 monitor    6u  IPv4  156403268      0t0  TCP *:monitor-agent (LISTEN)   
#sudo lsof -n -i TCP:8092 -s TCP:ESTABLISHED     //展示TCP端口8092且状态为ESTABLIESHED的情况 
COMMAND   PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME 
java    13413 root   94u  IPv4 844561512      0t0  TCP 192.168.20.30:59289->192.168.20.30:8092 (ESTABLISHED) 
TCP状态:CLOSED,IDLE,BOUND,LISTEN,ESTABLISHED,SYN_SENT,SYN_RCDV,CLOSE_WAIT,FIN_WAIT1,CLOSING,LAST_ACK,FIN_WAIT_2,TIME_WAIT 
UDB状态: Unbound , Idle 
-T 选项,显示网络端口的情况 
#sudo lsof -T q -i :1883     //显示QR(length of read queue), QS(length of send queue) 
COMMAND  PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME 
java    3603 root   49u  IPv4 884372618      0t0  TCP *:1883 (QR=0 QS=0) 
#sudo lsof -T s -i :80   //显示端口的状态 
COMMAND   PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
nginx    5604  www   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
查看某个文件的打开情况 
#sudo lsof /data/tomcat/ 
[sudo] password for wang: 
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME 
java    8743 root  cwd    DIR    8,8     4096 3014674 /www/data/tomcat 
#sudo lsof /dev/sda7     //某个文件系统的打开情况 
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME 
java       1818 root  mem    REG    8,7    32768 394070 /tmp/hsperfdata_root/1818 
+d 选项 
#sudo lsof +d /data/tomcat/    //搜索/data/tomcat/ 目录以及目录下文件,目录下目录打开情况,不会搜索子目录 
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME 
java    3603 root  cwd    DIR    8,8     4096 3014674 /www/data/tomcat 
-d 选项 
#sudo lsof -d 16   //查看16号FD的打开情况,因为每个进程有自己独立的文件描述符表。因此-d 16 会展示很多16号fd 
COMMAND     PID      USER   FD   TYPE     DEVICE SIZE/OFF       NODE NAME 
ntpd        553       ntp   16u  IPv4 1954763371      0t0        UDP *:ntp 
hald       1237 haldaemon   16r   REG        0,3        0 4026531979 /proc/mdstat 
+D 选项 
#sudo lsof +D /data/tomcat/    //查看/data/tomcat 以及所有子目录文件的打开情况 
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME 
python  2806 root    6r   REG    8,8   159675 3024730 /www/data/tomcat/logs/bigdata.log 
java    8743 root  cwd    DIR    8,8     4096 3014674 /www/data/tomcat 
java    8743 root  mem    REG    8,8   124266 3015949 /www/data/tomcat/lib/jasper-e 
-a 选项 多个条件AND 
#sudo lsof -i 4 -a -p 32463    //显示32463这个进程打开Ipv4的网络端口文件情况 
-U 显示所有Unix domain sockets相关情况 
#sudo lsof -U //显示所有Unix domain sockets  这是一种特殊的本机内进程通讯方式 
sudo       1808      root    4u  unix 0xffff88032a858d80      0t0 2191544754 socket 
java       2545      root   48u  unix 0xffff8802f487cec0      0t0 3146212706 socket 
sudo       2697      root    4u  unix 0xffff88010cadf7c0      0t0  841102828 socket 
java       2698      root   26u  unix 0xffff88032a859740      0t0  841102853 socket 
java       2698      root   36u  unix 0xffff88042b642f40      0t0  841102861 socket 
nginx      3096       www   17u  unix 0xffff880429f07400      0t0 4166624772 socket 
#sudo lsof -U -a -c java   //显示所有COMMAND中含有java,同时是Unix domain sockets的文件打开方式 
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF       NODE NAME 
java     2545 root   48u  unix 0xffff8802f487cec0      0t0 3146212706 socket 
java     2698 root   26u  unix 0xffff88032a859740      0t0  841102853 socket 
java     2698 root   36u  unix 0xffff88042b642f40      0t0  841102861 socket 
java     3241 root   53u  unix 0xffff8802fe1cbac0      0t0 3920291480 socket 
java     3241 root  172u  unix 0xffff8802fe1ca740      0t0 3920299347 socket 
java     3865 root   26u  unix 0xffff88019c8c8c00      0t0  841135846 socket 
java     3865 root   37u  unix 0xffff88022c3f9500      0t0  841136956 socket 
-l 选项,展示USER ID, 不展示具体用户名,辅助选项 
#sudo lsof -l -i :80    // -l USER这一列只展示ID,不展示具体的用户名 
COMMAND   PID     USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME 
nginx    5604      514   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
nginx    5605      514   16u  IPv4      82923      0t0  TCP *:http (LISTEN) 
-n 选项,展示主机ip而不是主机名,辅助选项 
#sudo lsof -n -i [email protected]  //展示把主机ip而不是主机名1 
redis-ser 6418 root 3231u  IPv4  871410697      0t0  TCP 192.168.20.30:6380->192.168.20.31:30085 (ESTABLISHED) 
-o 选项,把SIZE/OFF 换成OFFSET,辅助选项 
#sudo lsof -o  +d  /data/tomcat/   //把SIZE/OFF 换成OFFSET 
COMMAND  PID USER   FD   TYPE DEVICE OFFSET    NODE NAME 
java    3603 root  cwd    DIR    8,8        3014674 /www/data/tomcat 
-P 选项,实现端口数字,而不是端口含义,辅助选项 
# sudo lsof -P -i :80   //-P 直接显示端口号,而不是端口含义 
-r 选项,每隔多少秒显示一次,辅助选项 
#sudo lsof -i :80  -r 3     //每隔3秒显示一次lsof -i :80,直到ctrl+c 退出 
+r 选项,每隔多少秒显示一次,辅助选项 
#sudo lsof -i :80  +r 3     //每隔3秒显示一次lsof -i :80   直到lsof中没有数据了,或ctrl+c退出 
-s 选项,SIZE/OFF 只展示SIZE 辅助选项 
# sudo lsof -s  -p 32463     // -s  SIZE/OFF 只展示SIZE

恢复文件

利用lsof可以恢复一些系统日志,前提是这个进程必须存在。这里就拿最常用的/var/log/messages来举例说明,大家在做测试的时候最好先备份一下。

#备份 
shell> cp /var/log/message /var/log/message_bac shell> lsof |grep /var/log/message rsyslogd 1737 root 1w REG 8,2 5716123 652638 /var/log/messages

进程在运行中,接下来我就把/var/log/messages这个文件删掉

shell> rm /var/log/messages

删掉之后,我再来看看这个进程的变化

shell> lsof |grep /var/log/messages 
rsyslogd   1737      root    1w REG 8,2 5716123 652638 /var/log/messages (deleted)

大家看到有变化了吧, 对比两个之后发现多了(deleted)。要找到这个文件在哪还要看看这个

PID:1737 FD:1 那我们有直接进入/proc/1737/FD/1用ll查看一下

shell> cd /proc/1737/fd/ shell> ll total 0 lrwx------ 1 root root 64 Dec 23 13:00 0 -> socket:[11442] l-wx------ 1 root root 64 Dec 23 13:00 1 -> /var/log/messages (deleted) l-wx------ 1 root root 64 Dec 23 13:00 2 -> /var/log/secure lr-x------ 1 root root 64 Dec 23 13:00 3 -> /proc/kmsg l-wx------ 1 root root 64 Dec 23 13:00 4 -> /var/log/maillog

看到了1对应/var/log/messages (deleted),看看文件是不是我们要的文件:

shell> head -5 1 
Nov 14 03:11:11 localhost kernel: imklog 5.8.10, log source = /proc/kmsg started. Nov 14 03:11:11 localhost rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="1241" x-info="http://www.rsyslog.com"] start Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpuset Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpu Nov 14 03:11:11 localhost kernel: Linux version 2.6.32-431.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013

对比备份文件:

shell> head -5 /var/log/message_bac 
Nov 14 03:11:11 localhost kernel: imklog 5.8.10, log source = /proc/kmsg started. Nov 14 03:11:11 localhost rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="1241" x-info="http://www.rsyslog.com"] start Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpuset Nov 14 03:11:11 localhost kernel: Initializing cgroup subsys cpu Nov 14 03:11:11 localhost kernel: Linux version 2.6.32-431.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Nov 22 03:15:09 UTC 2013

对比发现数据是一样的,恢复

shell> cat 1 > /var/log/messages

再次提醒,恢复前提是这个进程必须存在。



以上信息来源于网络收集!

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/1804.html

(0)
上一篇 2021年7月15日
下一篇 2021年7月15日

相关推荐

发表回复

登录后才能评论