原来lsof用的比较少,才发现这命令特别好用,记录学习过程,感谢黄老师大讲堂的热心帮助,理解了不少原来没关注过的东西。
1.lsof命令的介绍
lsof(list open files)是一个列出当前系统打开文件的工具。众所周知,在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。
2.lsof命令默认输出
在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。每行显示一个打开的文件,若不指定条件默认将显示所有进程打开的所有文件。
[root@baynk ~]# lsof |more
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 72 /sbin/init
init 1 root mem REG 8,2 66432 653845 /lib64/libnss_files-2.12.so
init 1 root mem REG 8,2 1930416 662914 /lib64/libc-2.12.so
init 1 root mem REG 8,2 93320 662929 /lib64/libgcc_s-4.4.7-20120601.so.1
init 1 root mem REG 8,2 47760 662923 /lib64/librt-2.12.so
init 1 root mem REG 8,2 146592 662922 /lib64/libpthread-2.12.so
init 1 root mem REG 8,2 268232 662953 /lib64/libdbus-1.so.3.4.0
init 1 root mem REG 8,2 39896 657147 /lib64/libnih-dbus.so.1.0.0
init 1 root mem REG 8,2 101920 657149 /lib64/libnih.so.1.0.0
init 1 root mem REG 8,2 161704 662913 /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 8310 pipe
init 1 root 4w FIFO 0,8 0t0 8310 pipe
init 1 root 5r DIR 0,10 0 1 inotify
init 1 root 6r DIR 0,10 0 1 inotify
init 1 root 7u unix 0xffff8800377af780 0t0 8311 @/com/ubuntu/upstart
init 1 root 9u unix 0xffff88003d885880 0t0 11344 socket
lsof输出各列信息的意义如下:
COMMAND:进程的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
TYPE:文件类型,如DIR、REG等
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
简单说下比较难理解的项吧
FD 列中的文件描述符cwd值表示应用程序的当前工作目录,可能是该应用程序启动的目录。txt则代表是普通代码或者数据。还有其余的如下所示:
cwd current working directory;
Lnn library references (AIX);
err 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);
txt program text (code and data);
v86 VP/ix mapped file;
但是有些是以数值加字符表示的,初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的 FD 都是从 3 开始。比如u表示该文件被打开并处于读取/写入,而不是只读或只写。其余字符含义如下所示:
r for read access;
w for write access;
u for read and write access;
space if mode unknown and no lock character follows;
‘-’ if mode unknown and lock character follows
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.
Type 列则比较好理解。文件和目录分别称为 REG 和 DIR。而CHR 和 BLK,分别表示字符和块设备;
or ‘‘IPv4’’ for an IPv4 socket;
or ‘‘IPv6’’ for an open IPv6 network file - even if its address is IPv4, mapped in an IPv6 address;
or ‘‘ax25’’ for a Linux AX.25 socket;
or ‘‘inet’’ for an Internet domain socket;
or ‘‘lla’’ for a HP-UX link level access file;
or ‘‘rte’’ for an AF_ROUTE socket;
or ‘‘sock’’ for a socket of unknown domain;
or ‘‘unix’’ for a UNIX domain socket;
or ‘‘x.25’’ for an HP-UX x.25 socket;
or ‘‘BLK’’ for a block special file;
or ‘‘CHR’’ for a character special file;
or ‘‘DEL’’ for a Linux map file that has been deleted;
or ‘‘DIR’’ for a directory;
or ‘‘DOOR’’ for a VDOOR file;
or ‘‘FIFO’’ for a FIFO special file;
or ‘‘KQUEUE’’ for a BSD style kernel event queue file;
or ‘‘LINK’’ for a symbolic link file;
or ‘‘MPB’’ for a multiplexed block file;
or ‘‘MPC’’ for a multiplexed character file;
or ‘‘NOFD’’ for a Linux /proc/<PID>/fd directory that can’t be opened -- the directory path appears in the NAME column, fol-
lowed by an error message;
or ‘‘PAS’’ for a /proc/as file;
or ‘‘PAXV’’ for a /proc/auxv file;
or ‘‘PCRE’’ for a /proc/cred file;
or ‘‘PCTL’’ for a /proc control file;
or ‘‘PCUR’’ for the current /proc process;
or ‘‘PCWD’’ for a /proc current working directory;
or ‘‘PDIR’’ for a /proc directory;
or ‘‘PETY’’ for a /proc executable type (etype);
or ‘‘PFD’’ for a /proc file descriptor;
or ‘‘PFDR’’ for a /proc file descriptor directory;
or ‘‘PFIL’’ for an executable /proc file;
or ‘‘PFPR’’ for a /proc FP register set;
or ‘‘PGD’’ for a /proc/pagedata file;
or ‘‘PGID’’ for a /proc group notifier file;
or ‘‘PIPE’’ for pipes;
or ‘‘PLC’’ for a /proc/lwpctl file;
or ‘‘PLDR’’ for a /proc/lpw directory;
or ‘‘PLDT’’ for a /proc/ldt file;
or ‘‘PLPI’’ for a /proc/lpsinfo file;
or ‘‘PLST’’ for a /proc/lstatus file
or ‘‘PLU’’ for a /proc/lusage file;
or ‘‘PLWG’’ for a /proc/gwindows file;
or ‘‘PLWI’’ for a /proc/lwpsinfo file;
or ‘‘PLWS’’ for a /proc/lwpstatus file;
or ‘‘PLWU’’ for a /proc/lwpusage file;
or ‘‘PLWX’’ for a /proc/xregs file’
or ‘‘PMAP’’ for a /proc map file (map);
or ‘‘PMEM’’ for a /proc memory image file;
or ‘‘PNTF’’ for a /proc process notifier file;
or ‘‘POBJ’’ for a /proc/object file;
or ‘‘PODR’’ for a /proc/object directory;
or ‘‘POLP’’ for an old format /proc light weight process file;
or ‘‘POPF’’ for an old format /proc PID file;
or ‘‘POPG’’ for an old format /proc page data file;
or ‘‘PORT’’ for a SYSV named pipe;
or ‘‘PREG’’ for a /proc register file;
or ‘‘PRMP’’ for a /proc/rmap file;
or ‘‘PRTD’’ for a /proc root directory;
or ‘‘PSGA’’ for a /proc/sigact file;
or ‘‘PSIN’’ for a /proc/psinfo file;
or ‘‘PSTA’’ for a /proc status file;
or ‘‘PSXSEM’’ for a POSIX semaphore file;
or ‘‘PSXSHM’’ for a POSIX shared memory file;
or ‘‘PUSG’’ for a /proc/usage file;
or ‘‘PW’’ for a /proc/watch file;
or ‘‘PXMP’’ for a /proc/xmap file;
or ‘‘REG’’ for a regular file;
or ‘‘SMT’’ for a shared memory transport file;
or ‘‘STSO’’ for a stream socket;
or ‘‘UNNM’’ for an unnamed type file;
or ‘‘XNAM’’ for an OpenServer Xenix special file of unknown type;
or ‘‘XSEM’’ for an OpenServer Xenix semaphore file;
or ‘‘XSD’’ for an OpenServer Xenix shared data file;
or the four type number octets if the corresponding name isn’t known.
3.lsof使用方法
3.1 语法
[root@baynk ~]# lsof --help
usage: [-?abhlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[gG]] [+|-e s]
[-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]
lsof超多选项,一眼看上去还是挺唬人的,这里就介绍几个比较常用的吧。
3.2 常用参数列表
lsof filename 显示打开指定文件的所有进程
lsof -a 表示两个参数都必须满足时才显示结果
lsof -c string 显示COMMAND列中包含指定字符的进程所有打开的文件
lsof -u username 显示所属user进程打开的文件
lsof -g gid 显示归属gid的进程情况
lsof +d /DIR/ 显示目录下被进程打开的文件
lsof +D /DIR/ 同上,但是会搜索目录下的所有目录,时间相对较长
lsof -d FD 显示指定文件描述符的进程
lsof -n 不将IP转换为hostname,缺省是不加上-n参数
lsof -t 和其它选项联用,只显示PID
lsof -i [46] [protocol][@hostname|hostaddr][:service|port]用以显示符合条件的进程情况
3.3 查看文件被哪些进程占用
[root@baynk ~]# lsof /home/test/1.txt
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
more 6425 test 3r REG 8,2 641020 792796 /home/test/1.txt
3.4 查看文件或者目录下的文件被哪些进程占用
在umount报错时,经常可以使用到此功能。
[root@baynk test]# lsof /root/test
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 5870 root cwd DIR 8,2 4096 792787 /root/test
vim 6325 root cwd DIR 8,2 4096 792787 /root/test
lsof 6330 root cwd DIR 8,2 4096 792787 /root/test
lsof 6331 root cwd DIR 8,2 4096 792787 /root/test
这里就显示了有vim在占用文件系统内的资源
3.5 查找监听某端口的进程
[root@baynk test]# lsof -i:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1737 root 3u IPv4 11934 0t0 TCP *:ssh (LISTEN)
sshd 1737 root 4u IPv6 11936 0t0 TCP *:ssh (LISTEN)
sshd 5768 root 3r IPv4 20002 0t0 TCP 192.168.181.129:ssh->192.168.181.1:12752 (ESTABLISHED)
sshd 5868 root 3r IPv4 20490 0t0 TCP 192.168.181.129:ssh->192.168.181.1:13167 (ESTABLISHED)
3.6 查看关于某IP活动的连接情况
[root@baynk test]# lsof -i @192.168.181.1
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 5768 root 3r IPv4 20002 0t0 TCP 192.168.181.129:ssh->192.168.181.1:12752 (ESTABLISHED)
sshd 5868 root 3r IPv4 20490 0t0 TCP 192.168.181.129:ssh->192.168.181.1:13167 (ESTABLISHED)
3.7 查看除了某用户使用的进程
[root@baynk ~]# lsof -a -u ^root -c more
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
more 6469 test cwd DIR 8,2 4096 792792 /home/test
more 6469 test rtd DIR 8,2 4096 2 /
more 6469 test txt REG 8,2 41216 1044569 /bin/more
more 6469 test mem REG 8,2 134792 662960 /lib64/libtinfo.so.5.7
more 6469 test mem REG 8,2 161704 662913 /lib64/ld-2.12.so
more 6469 test mem REG 8,2 1930416 662914 /lib64/libc-2.12.so
more 6469 test mem REG 8,2 99174448 394905 /usr/lib/locale/locale-archive
more 6469 test mem REG 8,2 26060 395165 /usr/lib64/gconv/gconv-modules.cache
more 6469 test 0u CHR 136,1 0t0 4 /dev/pts/1
more 6469 test 1u CHR 136,1 0t0 4 /dev/pts/1
more 6469 test 2u CHR 136,1 0t0 4 /dev/pts/1
more 6469 test 3r REG 8,2 641020 792796 /home/test/1.txt (deleted)
上述例子中用了-a,代表同时要满足-u(指定用户)和-c(指定命令),不指定默认为“或”的关系。其中“^root”代表除了root以外的用户。
3.8 根据进程查打开的文件
[root@baynk ~]# lsof -p 6469
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
more 6469 test cwd DIR 8,2 4096 792792 /home/test
more 6469 test rtd DIR 8,2 4096 2 /
more 6469 test txt REG 8,2 41216 1044569 /bin/more
more 6469 test mem REG 8,2 134792 662960 /lib64/libtinfo.so.5.7
more 6469 test mem REG 8,2 161704 662913 /lib64/ld-2.12.so
more 6469 test mem REG 8,2 1930416 662914 /lib64/libc-2.12.so
more 6469 test mem REG 8,2 99174448 394905 /usr/lib/locale/locale-archive
more 6469 test mem REG 8,2 26060 395165 /usr/lib64/gconv/gconv-modules.cache
more 6469 test 0u CHR 136,1 0t0 4 /dev/pts/1
more 6469 test 1u CHR 136,1 0t0 4 /dev/pts/1
more 6469 test 2u CHR 136,1 0t0 4 /dev/pts/1
more 6469 test 3r REG 8,2 641020 792796 /home/test/1.txt (deleted)
3.9 磁盘空间不一致
[root@baynk ~]# lsof |grep delete
mysqld 1876 mysql 4u REG 8,2 0 1044499 /tmp/ibhQcgmW (deleted)
mysqld 1876 mysql 5u REG 8,2 0 1044502 /tmp/ib7IMu0c (deleted)
mysqld 1876 mysql 6u REG 8,2 0 1044575 /tmp/ibV3sJEt (deleted)
mysqld 1876 mysql 7u REG 8,2 0 1045191 /tmp/ibwCZ4kK (deleted)
mysqld 1876 mysql 11u REG 8,2 0 1045334 /tmp/ibaUgUa1 (deleted)
more 6469 test 3r REG 8,2 641020 792796 /home/test/1.txt (deleted)
有些删了文件,但是进程没 reload,那些空间还是占用的,打到进程然后kill就OK了。
3.10 恢复文件内容
模拟场景,用more打开一个1.txt(内容为/etc/services的内容)文件,然后删除此文件,当然,现实生活中更多的是日志文件被删除,至于原因嘛,手动滑稽。
1.查看还有没有进程打开着此文件
[root@baynk ~]# lsof |grep /home/test/1.txt
more 6469 test 3r REG 8,2 641020 792796 /home/test/1.txt (deleted)
[root@baynk ~]#
2.发现more这个命令还在打开此文件,后面也说明1.txt已经被删除了。接着去/proc中查找对应的pid,结合fd来找到对应的内容。
[root@baynk ~]# cat /proc/6469/fd/3 |more
# /etc/services:
# $Id: services,v 1.48 2009/11/11 14:32:31 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2009-11-10
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, most entries here have two entries
# even if the protocol doesn't support UDP operations.
# Updated from RFC 1700, ``Assigned Numbers'' (October 1994). Not all ports
# are included, only the more common ones.
#
# The latest IANA port assignments can be gotten from
# http://www.iana.org/assignments/port-numbers
# The Well Known Ports are those from 0 through 1023.
# The Registered Ports are those from 1024 through 49151
# The Dynamic and/or Private Ports are those from 49152 through 65535
#
# Each line describes one service, and is of the form:
3.OK,就是所对应的内容。最后使用重定向导入即可。
[root@baynk ~]# cat /proc/6469/fd/3 > /home/test/1.txt;more /home/test/1.txt
# /etc/services:
# $Id: services,v 1.48 2009/11/11 14:32:31 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2009-11-10
#
# Note that it is presently the policy of IANA to assign a single well-known
# port number for both TCP and UDP; hence, most entries here have two entries
# even if the protocol doesn't support UDP operations.
# Updated from RFC 1700, ``Assigned Numbers'' (October 1994). Not all ports
# are included, only the more common ones.
#
# The latest IANA port assignments can be gotten from
# http://www.iana.org/assignments/port-numbers
# The Well Known Ports are those from 0 through 1023.
# The Registered Ports are those from 1024 through 49151
# The Dynamic and/or Private Ports are those from 49152 through 65535
尾语
“渗透千万条,安全第一条。日志不删完,亲人泪两行”