一. lsof 使用场景
- lsof(list open files)的作用是列出当前系统打开的文件
二. lsof 命令安装
[root@bi ~]# lsof
-bash: lsof: command not found
[root@bi ~]# yum install lsof
Loaded plugins: fastestmirror
Determining fastest mirrors
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.huaweicloud.com
base | 3.6 kB 00:00:00
extras | 2.9 kB 00:00:00
updates | 2.9 kB 00:00:00
extras/7/x86_64/primary_db | 242 kB 00:00:00
Resolving Dependencies
--> Running transaction check
---> Package lsof.x86_64 0:4.87-6.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=========================================================================================================
Package Arch Version Repository Size
=========================================================================================================
Installing:
lsof x86_64 4.87-6.el7 base 331 k
Transaction Summary
=========================================================================================================
Install 1 Package
Total download size: 331 k
Installed size: 927 k
Is this ok [y/d/N]: y
Downloading packages:
lsof-4.87-6.el7.x86_64.rpm | 331 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : lsof-4.87-6.el7.x86_64 1/1
Verifying : lsof-4.87-6.el7.x86_64 1/1
Installed:
lsof.x86_64 0:4.87-6.el7
Complete!
[root@bi ~]# lsof
一堆...
三. 常用参数搭配示例
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# 分屏列出系统打开的文件
[root@bi ~]# lsof |more
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,0 224 64 /
systemd 1 root rtd DIR 253,0 224 64 /
systemd 1 root txt REG 253,0 1624552 67457132 /usr/lib/systemd/systemd
# 查看这个文件是否被打开及应用情况
[root@bi ~]# lsof /home/hello/filename
# 分屏列出root用户打开的文件
[root@bi ~]# lsof -u root | more
# 列出所有的tcp连接信息
[root@bi ~]# lsof -i tcp
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1724 root 3u IPv4 15915 0t0 TCP *:ssh (LISTEN)
sshd 1724 root 4u IPv6 15917 0t0 TCP *:ssh (LISTEN)
master 2007 root 13u IPv4 27787 0t0 TCP localhost:smtp (LISTEN)
master 2007 root 14u IPv6 27788 0t0 TCP localhost:smtp (LISTEN)
sshd 24475 root 3u IPv4 15299584 0t0 TCP bi.life.cib:ssh->108.95.165.151:47748 (ESTABLISHED) (此IP为虚构)
# 列出哪些文件在使用指定的端口
[root@bi ~]# lsof -i:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1724 root 3u IPv4 15915 0t0 TCP *:ssh (LISTEN)
sshd 1724 root 4u IPv6 15917 0t0 TCP *:ssh (LISTEN)
sshd 24475 root 3u IPv4 15299584 0t0 TCP bi.life.cib:ssh->103.85.164.150:47748 (ESTABLISHED)
# 列出root用户的所有活跃端口
[root@bi ~]# lsof -a -u root -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1724 root 3u IPv4 15915 0t0 TCP *:ssh (LISTEN)
sshd 1724 root 4u IPv6 15917 0t0 TCP *:ssh (LISTEN)
master 2007 root 13u IPv4 27787 0t0 TCP localhost:smtp (LISTEN)
master 2007 root 14u IPv6 27788 0t0 TCP localhost:smtp (LISTEN)
sshd 24475 root 3u IPv4 15299584 0t0 TCP bi.life.cib:ssh->108.95.165.151:47748 (ESTABLISHED) (此IP为虚构)
# 递归列出该目录下所有被系统打开的文件信息
[root@bi ~]# lsof +D /home/hello/
四.参数释义
-
1、输出的内容中,关于列字段的解释
COMMAND
:进程的名称
PID
:进程标识符
USER
:进程所有者
FD
:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
TYPE
:文件类型,如DIR、REG等
DEVICE
:指定磁盘的名称
SIZE
:文件的大小
NODE
:索引节点(文件在磁盘上的标识)
NAME
:打开文件的确切名称 -
2、常用参数列表
lsof filename
:显示打开指定文件的所有进程
lsof -a
: 表示两个参数都必须满足时才显示结果
lsof -c string
: 显示COMMAND列中包含指定字符的进程所有打开的文件
lsof -u username
: 显示所属user进程打开的文件
lsof -g gid
: 显示归属gid的进程情况,即组ID
lsof +d /DIR/
: 显示目录下被进程打开的文件
lsof +D /DIR/
: 同上,但是会搜索目录下的所有目录,时间相对较长,也就是递归查找
lsof -d FD
显示指定文件描述符的进程
lsof -n
不将IP转换为hostname,缺省是不加上-n参数
lsof -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 –> 端口号(支持多个)
五. 实际使用场景
5.1 释放已经删除的文件空间
使用rm 删除了文件,但某些情况并未真正释放,导致我们看到文件删除了,但是磁盘空间还被占用, 可能会出现可用磁盘空间+已占用文件大小<磁盘空间
的情况, 若要释放这些空间, 1. 重启服务器,但谁会没事重启服务器? 2. 关闭文件的使用进程后释放,那怎么找到这个进程呢?
两条关键命令:
lsof -n | grep deleted
: 列出被标记为deleted的文件
kill -9 pid
杀死这个进程.
[root@bi ~]# lsof -n |grep deleted
firewalld 1398 root 6u REG 253,0 4096 67742064 /tmp/ffiuS9cg1 (deleted)
gmain 1398 1547 root 6u REG 253,0 4096 67742064 /tmp/ffiuS9cg1 (deleted)
tuned 1722 root 8u REG 253,0 4096 67586475 /tmp/ffitOyyhZ (deleted)
gmain 1722 2104 root 8u REG 253,0 4096 67586475 /tmp/ffitOyyhZ (deleted)
tuned 1722 2105 root 8u REG 253,0 4096 67586475 /tmp/ffitOyyhZ (deleted)
tuned 1722 2113 root 8u REG 253,0 4096 67586475 /tmp/ffitOyyhZ (deleted)
tuned 1722 2184 root 8u REG 253,0 4096 67586475 /tmp/ffitOyyhZ (deleted)
[root@bi ~]# ps -ef | grep 1722
root 1722 1 0 Apr28 ? 00:07:40 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
root 24594 24478 0 11:49 pts/0 00:00:00 grep --color=auto 1722
[root@bi ~]# kill 1722
[root@bi ~]# lsof -n |grep deleted
firewalld 1398 root 6u REG 253,0 4096 67742064 /tmp/ffiuS9cg1 (deleted)
gmain 1398 1547 root 6u REG 253,0 4096 67742064 /tmp/ffiuS9cg1 (deleted)
[root@bi ~]#
5.2 恢复已经删除的文件(过程)
以恢复mysql日志的方法,前提: mysql是在运行状态中的
[root@bi hello]# cat /var/log/mysql.log
(省略)...
[root@bi hello]# rm -rf /var/log/mysql.log
[root@bi hello]# ll /var/log/mysql.log
ls: cannot access text.txt: No such file or directory
[root@bi hello]# lsof |grep mysql.log
(省略)...
[root@bi hello]# ll /proc/1721/fd (1721是我的PID)
(省略)...
[root@bi hello]# cat /var/log/mysql.log | more
(省略)...
[root@bi hello]# cat /proc/1721/fd/1 > /var/log/mysql.log
[root@bi hello]# chown root /var/log/mysql.log (将文件改为原来的拥有者, 我这是root)