lsof命令
用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户执行。
在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。
输出信息的含义
在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。
直接输入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