Linux 命令之 lsof -- 列出当前系统已打开的文件列表

文章目录

  • 命令介绍
  • 常用选项
  • 字段说明
  • 文件类型
  • 文件描述符
  • 文件状态模式
  • 锁模式
  • 参考示例
    • (一)查看打开指定文件的所有进程
    • (二)列出由某个 PID 对应的进程打开的所有文件
    • (三)查看指定名称的进程所打开的文件列表
    • (四)列出除了某个用户以外的被打开的文件列表
    • (五)列出除了某个进程之外,其它进程打开的文件列表
    • (六)列出所有的网络连接
    • (七)列出所有的 TCP 网络连接
    • (八)列出所有的 UDP 网络连接
    • (九)查看有哪些进程在使用指定的端口
    • (十)查看哪些进程在使用指定的 UDP 端口
    • (十一)查看哪些进程在使用指定的 TCP 端口
    • (十二)列出某个用户所有活跃的网络端口
    • (十三)查看指定用户组所打开的文件列表
    • (十四)根据文件描述符的范围查看有关的文件列表
    • (十五)哪些进程在使用 apache 的可执行文件
    • (十六)查看连接到某个远程主机端口的进程
    • (十七)不断查看远程主机 ftp 连接的情况
    • (十八)递归查找某个目录中所有打开的文件
    • (十九)列出某个用户打开的所有文件
    • (二十)列出由某个用户或某个进程打开的所有文件
    • (二十一)查看某个用户的所有网络连接
    • (二十二)列出所有内存映射文件
    • (二十三)列出所有加载在内存中并正在执行的进程
    • (二十四)查看使用网络资源的进程 pid
    • (二十五)杀掉所有使用网络的进程
    • (二十六)循环列出文件
    • (二十七)查看被打开的和网络相关的文件
    • (二十八)统计系统打开的文件总数
    • (二十九)杀掉属于某个用户的打开了文件的所有进程
    • (三十)列出某个 IP 的网络连接信息
    • (三十一)同时列出连接某主机多个端口的网络连接文件
  • 经典场景应用
    • (一)查看指定进程打开的特定文件(查看日志文件路径)
    • (二)查看文件的内存映射路径(查看已删除文件的内容)
    • (三)恢复被删除的文件
    • (四) 日志文件删除后磁盘空间可用空间没有变大,怎么解决

命令介绍

lsofList Opened Files 的缩写,该命令是用于列出当前系统打开的文件的工具,也就是查看被进程打开的文件的工具,且可以用来找回或恢复被删除的文件。

在 Linux 下“一切皆文件”,任何事物都以文件的形式存在,包括但不限于 pipes, sockets, directories, devices等。通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件,例如:传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等。

lsof 是一个 Linux 下的非常实用和方便的系统级的监控、诊断工具。因为 lsof 命令需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。

系统在后台为每个应用程序分配了一个文件描述符(程序打开文件,系统都会分配一个文件描述符给该程序),该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过 lsof 工具查看这个列表,对系统监测以及排错将是很有帮助的。

lsof 显示的结果中,每行显示一个打开的文件,若不指定条件默认显示所有进程打开的所有文件。

常用选项

选项说明
-a指示多个选项之间为 的关系,必须都满足时才显示结果
-c<进程名>列出指定进程所打开的文件
-g显示归属于 GID 的进程情况
-d<文件号>列出占用该文件号的进程,文件号就是文件描述符。例如:显示使用fd为4的进程
+d<目录>列出指定目录下被打开的文件
+D<目录>递归列出指定目录下被打开的文件
-n<目录>列出使用NFS的文件
-n不解析主机名 ,不将 IP 转换为 Host Name,缺省是不加上 -n 选项,疑问??
-i<条件>列出符合条件的且与网络相关的进程。(4、6、协议、:端口、 @ip )不加条件默认列出所有的网络连接。
-p<进程号>列出指定进程号所打开的文件
-P不解析端口号
-N列出所有NFS(网络文件系统)文件
-u<用户名>列出指定用户打开的文件, 该选项可以指定用户名 或 user ID,可以通过逗号分隔多个用户名称或 user ID,也可以通过符号 ^ 对条件取反
-U列出所有UNIX域Socket文件
-t只输出 PID
-h显示帮助信息
-v显示版本信息

字段说明

字段名称说明
COMMAND进程的名称,默认以 9 个字符长度显示的命令名称。可使用 +c 参数指定显示的宽度,若 +c 后跟的参数为零,则显示命令的全名。这个 +c 参数好像无效
PID进程标识符
PPID父进程标识符,父进程的IP号,默认不显示,当使用 -R 参数可打开。
USER进程所有者,命令的执行 UID 或系统中登陆的用户名称。默认显示为用户名,当使用 -l 参数时,可显示 UID。
PGID进程所属组标识符,进程组的ID 编号,默认也不会显示,当使用 -g 参数时可打开。
FDFile Descriptor Number,文件描述符,应用程序通过文件描述符识别文件,例如:cwd、txt 等
TYPE文件类型,例如: DIR、REG 等
DEVICE指定磁盘的名称,以逗号分隔设备编号,使用character special、block special表示的设备号
SIZE文件的大小,如果不能用大小表示的,会留空。使用-s参数控制。
NODE索引节点(文件在磁盘上的标识),本地文件的node码,或者协议,如TCP等
NAME打开文件的确切名称,挂载点和文件的全路径(链接会被解析为实际路径),或者连接双方的地址和端口、状态等

文件类型

英文标识说明
REG普通文件
DIR表示目录
CHR表示字符类型
BLK块设备类型
UNIXUNIX 域套接字,UNIX Domain Sockets
FIFO先进先出 (FIFO) 队列
IPv4/IPv6网际协议 (IP) 套接字,IPv4/IPv6 套接字
LINK链接文件

文件描述符

描述符说明
cwdCurrent Work Director 的缩写,应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
txt该类型的文件是程序代码,表示程序的可执行文件
lnnlibrary references (AIX)
erFD information error (see NAME column)
jldjail directory (FreeBSD)
ltxshared library text (code and data)
mxxhex memory-mapped type number xx
m86DOS Merge mapped file
memmemory-mapped file,表示内存映射文件
mmapmemory-mapped device
pdparent directory
rtdroot directory,表示根目录
trkernel trace file (OpenBSD)
v86VP/ix mapped file
0表示标准输出
1表示标准输入
2表示标准错误

文件状态模式

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

文件状态模式说明
u表示该文件被打开并处于读取/写入模式,例如:10u,10 是打开该文件时返回的一个整数,表示文件号是10,u 表示该文件被打开且处于读取/写入模式
r表示该文件被打开并处于只读模式
w表示该文件被打开并处于只写模式
space表示该文件的状态模式为 unknow,且没有锁定
-表示该文件的状态模式为 unknow,且被锁定

锁模式

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

锁模式说明
Nfor a Solaris NFS lock of unknown type
rfor read lock on part of the file
Rfor a read lock on the entire file
wfor a write lock on part of the file(文件的部分写锁)
Wfor a write lock on the entire file(整个文件的写锁)。表示该应用程序拥有对整个文件的写锁(表示该进程拥有对文件写操作的锁),该文件描述符用于确保每次只能打开一个应用程序实例。初始打开每个应用程序时,都具有三个文件描述符,从 0 到 2,分别表示标准输入、标准输出和标准错误。所以大多数应用程序所打开的文件的 FD 都是从 3 开始。
ufor a read and write lock of any length
Ufor a lock of unknown type
xfor an SCO OpenServer Xenix lock on part of the file
Xfor an SCO OpenServer Xenix lock on the entire file
spaceif there is no lock。表示该文件的状态模式为 unknow,且没有锁定。
-表示该文件的状态模式为 unknow,且被锁定。

参考示例

(一)查看打开指定文件的所有进程

  1. 查看哪些进程正在使用文件 /var/log/mysqld.log
[root@htlwk0001host ~]# lsof /var/log/mysqld.log
COMMAND     PID  USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
mysqld  1064381 mysql    1w   REG  253,1  3240699 935706 /var/log/mysqld.log
mysqld  1064381 mysql    2w   REG  253,1  3240699 935706 /var/log/mysqld.log
  1. 哪些进程在占用文件 /etc/passwd
[root@htlwk0001host ~]# lsof /etc/passwd
  1. 哪些进程在占用 hda6:
[root@htlwk0001host ~]# lsof /dev/hda6 
  1. 哪些进程在占用光驱:
[root@htlwk0001host ~]# lsof /dev/cdrom 

(二)列出由某个 PID 对应的进程打开的所有文件

查看 PID 为 1064381 的进程所打开的全部文件列表:

[root@htlwk0001host ~]# lsof -p 1064381
COMMAND     PID  USER   FD   TYPE             DEVICE  SIZE/OFF      NODE NAME
mysqld  1064381 mysql  cwd    DIR              253,1      4096    636744 /var/lib/mysql
mysqld  1064381 mysql  rtd    DIR              253,1       244       128 /
mysqld  1064381 mysql  txt    REG              253,1 251816000  51228705 /usr/sbin/mysqld
mysqld  1064381 mysql  mem    REG              253,1    553480  50342901 /usr/lib64/libpcre2-8.so.0.7.1
mysqld  1064381 mysql  mem    REG              253,1    304848  50342907 /usr/lib64/libselinux.so.1

(三)查看指定名称的进程所打开的文件列表

查看进程 mysqld 所打开的全部文件列表:

[root@htlwk0001host ~]# lsof -c mysqld
COMMAND     PID  USER   FD   TYPE             DEVICE  SIZE/OFF      NODE NAME
mysqld  1064381 mysql  cwd    DIR              253,1      4096    636744 /var/lib/mysql
mysqld  1064381 mysql  rtd    DIR              253,1       244       128 /
mysqld  1064381 mysql  txt    REG              253,1 251816000  51228705 /usr/sbin/mysqld
mysqld  1064381 mysql  mem    REG              253,1    553480  50342901 /usr/lib64/libpcre2-8.so.0.7.1
mysqld  1064381 mysql  mem    REG              253,1    304848  50342907 /usr/lib64/libselinux.so.1
mysqld  1064381 mysql  mem    REG              253,1     33224  50343274 /usr/lib64/libuuid.so.1.3.0

-c 选项限定只列出以 mysqld 开头的进程打开的文件:

你同样可以制定多个 -c 参数:

[root@htlwk0001host ~]# lsof -c apache -c python

这会列出所有由 apache 和 python 打开的文件。

(四)列出除了某个用户以外的被打开的文件列表

[root@htlwk0001host ~]# lsof -u ^root
COMMAND       PID     TID TASKCMD              USER   FD      TYPE             DEVICE  SIZE/OFF      NODE NAME
polkitd       715                           polkitd  cwd       DIR              253,1       244       128 /
polkitd       715                           polkitd  rtd       DIR              253,1       244       128 /

说明:^ 符号,表示 取反 的意思。

(五)列出除了某个进程之外,其它进程打开的文件列表

[root@htlwk0001host ~]# lsof -p ^1234

(六)列出所有的网络连接

列出所有打开了网络套接字(TCP和UDP)的进程:

[root@htlwk0001host ~]# lsof -i
COMMAND       PID            USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
chronyd       743          chrony    5u  IPv4    20334      0t0  UDP localhost:323 
chronyd       743          chrony    6u  IPv6    20335      0t0  UDP localhost:323 
NetworkMa     901            root   24u  IPv4    22817      0t0  UDP htlwk0001host:bootpc->_gateway:bootps 
systemd-r     955 systemd-resolve   12u  IPv4    23063      0t0  UDP *:hostmon 
systemd-r     955 systemd-resolve   13u  IPv4    23064      0t0  TCP *:hostmon (LISTEN)

(七)列出所有的 TCP 网络连接

[root@htlwk0001host ~]# lsof -i tcp
COMMAND       PID            USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
systemd-r     955 systemd-resolve   13u  IPv4    23064      0t0  TCP *:hostmon (LISTEN)
systemd-r     955 systemd-resolve   15u  IPv6    23067      0t0  TCP *:hostmon (LISTEN)
nginx       26556            root    8u  IPv4   137518      0t0  TCP *:http (LISTEN)
nginx       26556            root    9u  IPv4   137519      0t0  TCP *:https (LISTEN)
nginx       26556            root   10u  IPv6   137520      0t0  TCP *:https (LISTEN)
nginx       26556            root   11u  IPv6   137521      0t0  TCP *:http (LISTEN)
svnserve    34295            root    3u  IPv4   182743      0t0  TCP *:svn (LISTEN)
httpd       34871            root    4u  IPv6   186113      0t0  TCP *:tproxy (LISTEN)

tcp 选项会强制 lsof 只列出打开 TCP sockets 的进程。

(八)列出所有的 UDP 网络连接

[root@htlwk0001host ~]# lsof -i udp
COMMAND   PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd   743          chrony    5u  IPv4  20334      0t0  UDP localhost:323 
chronyd   743          chrony    6u  IPv6  20335      0t0  UDP localhost:323 
NetworkMa 901            root   24u  IPv4  22817      0t0  UDP htlwk0001host:bootpc->_gateway:bootps 
systemd-r 955 systemd-resolve   12u  IPv4  23063      0t0  UDP *:hostmon 
systemd-r 955 systemd-resolve   14u  IPv6  23066      0t0  UDP *:hostmon 
systemd-r 955 systemd-resolve   18u  IPv4  23069      0t0  UDP 127.0.0.53:domain 

(九)查看有哪些进程在使用指定的端口

lsof 列出占用 TCPUDP3306 端口的进程:

[root@htlwk0001host ~]# lsof -i:3306
COMMAND     PID  USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    1050299  root   72u  IPv6 19427946      0t0  TCP htlwk0001host:60664->47.114.59.224:mysql (ESTABLISHED)
java    1050299  root   78u  IPv6 19427982      0t0  TCP htlwk0001host:60704->47.114.59.224:mysql (ESTABLISHED)
java    1050299  root   79u  IPv6 19427963      0t0  TCP htlwk0001host:60684->47.114.59.224:mysql (ESTABLISHED)
java    1050299  root   80u  IPv6 19427972      0t0  TCP htlwk0001host:60696->47.114.59.224:mysql (ESTABLISHED)

你也可以使用 /etc/services 中制定的端口名称来代替端口号,比如:

[root@htlwk0001host ~]# lsof -i :smtp

(十)查看哪些进程在使用指定的 UDP 端口

[root@htlwk0001host ~]# lsof -i udp:55

(十一)查看哪些进程在使用指定的 TCP 端口

[root@htlwk0001host ~]# lsof -i tcp:55

(十二)列出某个用户所有活跃的网络端口

[root@htlwk0001host ~]# lsof -a -u test -i

(十三)查看指定用户组所打开的文件列表

查找所有 PGID 为 5555 的进程打开的文件:

[root@htlwk0001host ~]# lsof -g 5555;

(十四)根据文件描述符的范围查看有关的文件列表

  1. 显示使用 fd 为 2-3 的进程:
[root@htlwk0001host ~]# lsof -d 2-3
COMMAND       PID            USER   FD      TYPE             DEVICE  SIZE/OFF      NODE NAME
systemd         1            root    2u      CHR                1,3       0t0      6597 /dev/null
systemd         1            root    3w      CHR               1,11       0t0      6603 /dev/kmsg

上面的命令会列出所有描述符为 2 或 3 的文件。

  1. 显示使用 fd 为 4 的进程:
[root@htlwk0001host ~]# lsof -d 4
COMMAND       PID            USER   FD      TYPE             DEVICE SIZE/OFF     NODE NAME
systemd         1            root    4u  a_inode               0,14        0     9454 [eventpoll]
systemd-j     560            root    4u     unix 0xffff944b07050480      0t0    11200 /run/systemd/journal/socket type=DGRAM
systemd-u     587            root    4u  netlink                         0t0    17814 KOBJECT_UEVENT
auditd        673            root    4u     unix 0xffff944b2d4e8d80      0t0   380481 type=STREAM

上面这个命令会列出所有以描述符 4 打开的文件。

(十五)哪些进程在使用 apache 的可执行文件

[root@htlwk0001host ~]# lsof `which httpd`
COMMAND     PID   USER  FD   TYPE DEVICE SIZE/OFF     NODE NAME
httpd     34871   root txt    REG  253,1   580064 53187782 /usr/sbin/httpd
httpd   1048930 apache txt    REG  253,1   580064 53187782 /usr/sbin/httpd
httpd   1048931 apache txt    REG  253,1   580064 53187782 /usr/sbin/httpd
httpd   1049032 apache txt    REG  253,1   580064 53187782 /usr/sbin/httpd
httpd   1049033 apache txt    REG  253,1   580064 53187782 /usr/sbin/httpd
httpd   1049411 apache txt    REG  253,1   580064 53187782 /usr/sbin/httpd

(十六)查看连接到某个远程主机端口的进程

  1. 哪些进程打开了到 www.dpqyw.com 的UDP 端口 8088(ntp) 的连接:
[root@htlwk0001host ~]# lsof -i UDP@www.dpqyw.com:8088
  1. 哪些进程打开了到 192.168.2.245 TCP 端口 1521 的连接:
[root@svr-db-test ~]# lsof -i tcp@192.168.2.245:1521 -n

lsof -n 不将IP转换为hostname,缺省是不加上-n参数。

(十七)不断查看远程主机 ftp 连接的情况

[root@htlwk0001host ~]# lsof -i tcp@www.dpqyw.com:ftp -r -n
=======
=======
=======

说明:

  1. -rlsof 会永远不断的执行,直到收到中断信号
  2. +rlsof 会一直执行,直到没有档案被显示,缺省是 15s 刷新
  3. -n 不将 IP 转换为 hostname,缺省是不加上 -n 参数

(十八)递归查找某个目录中所有打开的文件

[root@htlwk0001host ~]# lsof +D /usr/lib

加上+D 参数,lsof 会对指定目录进行递归查找,注意这个参数要比 grep 版本慢:

[root@htlwk0001host ~]# lsof | grep '/usr/lib'

之所以慢是因为+D首先查找所有的文件,然后一次性输出。

(十九)列出某个用户打开的所有文件

[root@htlwk0001host ~]# lsof -u liaowenxiong

-u 选项限定只列出所有被用户 liaowenxiong 打开的文件,你可以通过逗号指定多个用户:

[root@htlwk0001host ~]# lsof -u liaowenxiong,liudehua

这条命令会列出 liaowenxiong 和 liudehua 用户打开的所有文件。

你也可以像下面这样使用多个 -u 做同样的事情:

[root@htlwk0001host ~]# lsof -u liaowenxiong -u root

(二十)列出由某个用户或某个进程打开的所有文件

[root@htlwk0001host ~]# lsof -u pkrumins -c apache

你可以组合使用多个选项,这些选项默认进行 关联,也就是说上面的命令会输出由用户 pkrumins 或者进程 apache 打开的文件,若希望多个选项之间是 关联,可用加上选项 -a

(二十一)查看某个用户的所有网络连接

查看用户 root 的所有网络连接:

[root@htlwk0001host ~]# lsof -a -u root -i
COMMAND       PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
NetworkMa     901 root   24u  IPv4    22817      0t0  UDP htlwk0001host:bootpc->_gateway:bootps 
nginx       26556 root    8u  IPv4   137518      0t0  TCP *:http (LISTEN)
nginx       26556 root    9u  IPv4   137519      0t0  TCP *:https (LISTEN)
nginx       26556 root   10u  IPv6   137520      0t0  TCP *:https (LISTEN)

使用 -a-u-i 选项组合可以让 lsof 列出某个用户的所有网络行为。

(二十二)列出所有内存映射文件

[root@htlwk0001host ~]#  lsof -d mem

(二十三)列出所有加载在内存中并正在执行的进程

[root@htlwk0001host ~]# lsof -d txt

(二十四)查看使用网络资源的进程 pid

[root@htlwk0001host ~]# lsof -t -i

-t 选项输出进程的 PID,你可以将它和 -i 选项组合输出使用某个端口的进程的 PID,如下:

[root@htlwk0001host ~]# lsof -t -i:3306
1050299
1050398
1064381

(二十五)杀掉所有使用网络的进程

[root@htlwk0001host ~]# kill -9 'lsof -t -i'

(二十六)循环列出文件

[root@htlwk0001host ~]# lsof -r 1

-r 选项让 lsof 可以循环列出文件直到被中断,参数1 就是循环间隔时间是 1 秒,即循环周期是 1 秒,意思是每秒钟重复打印一次,这个选项最好同某个范围比较小的查询组合使用,比如用来监测用户的网络活动:

[root@htlwk0001host ~]# lsof -r 1 -u john -i -a

(二十七)查看被打开的和网络相关的文件

使用 -i 选项用来查看网络相关的文件,其参数的格式如下:

lsof -i [46][protocol][@hostname|hostaddr][:service|port]

说明:

  1. 46 表示 IP 协议的版本
  2. protocol 表示网络协议的名称,比如 TCP 或 UDP
  3. hostnamehostaddr 表示主机域名或者主机 IP 地址
  4. service 指 /etc/services 中的端口名称,比如:smtp
  5. port 表示端口号,可以指定一个或多个

-i 选项默认会同时输出 IPv4 和 IPv6 打开的文件。

  1. 只列出 IPv4 或 IPv6 打开的文件:
[root@htlwk0001host ~]# lsof -i 4
[root@htlwk0001host ~]# lsof -i 6
  1. 列出占用一定端口范围的所有的进程:
[root@htlwk0001host ~]#lsof -i TCP:1-1024

(二十八)统计系统打开的文件总数

[root@htlwk0001host ~]# lsof -P -n | wc -l
69360

命令中的 -P 选项表示不解析端口号,-n 选项表示不解析主机名,这两个选项主要的目的是为了提升 lsof 命令的执行速度。wc -l 命令则用来统计 lsof 命令输出的行数。

(二十九)杀掉属于某个用户的打开了文件的所有进程

[root@htlwk0001host ~]# kill -9 `lsof -t -u nick`
[root@htlwk0001host ~]# kill -9 $(lsof -t -u nick)

(三十)列出某个 IP 的网络连接信息

[root@htlwk0001host ~]# lsof -i @47.114.59.256
COMMAND     PID  USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    1050299  root   72u  IPv6 19473546      0t0  TCP htlwk0001host:36448->47.114.59.224:mysql (ESTABLISHED)
java    1050299  root   78u  IPv6 19472650      0t0  TCP htlwk0001host:36488->47.114.59.224:mysql (ESTABLISHED)
java    1050299  root   79u  IPv6 19473549      0t0  TCP htlwk0001host:36450->47.114.59.224:mysql (ESTABLISHED)

(三十一)同时列出连接某主机多个端口的网络连接文件

列出目前连接主机 hadoop 的端口为:20,21,22,25,53,80 的所有文件信息,且每隔3秒不断的执行 lsof 指令:

[root@htlwk0001host ~]# lsof -i @hadoop:20,21,22,25,53,80  -r  3

经典场景应用

(一)查看指定进程打开的特定文件(查看日志文件路径)

场景描述:

同事今天请假了,但负责的 webserver 服务出现了问题,老板让你看一下 webserver 服务的日志,但你不知道 webserver 服务的日志文件路径,配置文件太复杂你不太懂,这时你可以执行以下命令查看日志文件路径。

[devl@xungen ~]$ lsof -c webserver | grep -e 'log$'
webserver  10124  devl  4u  REG 253,1  8814787  109523 /home/devl/application/webserver/log/webserver.00.log

(二)查看文件的内存映射路径(查看已删除文件的内容)

场景描述:

新来的同事误删除了 webserver 服务的日志文件,现在线上环境出现问题,需要查看 webserver 的日志,老板让紧急处理一下,这时你只能通过日志文件的内存映射路径来查看日志内容,那么怎么获取文件的内存映射路径呢?你要记住内存映射路径的固定格式:/proc/进程ID/fd/句柄。接着你要知道 webserver 进程 ID 和日志文件的句柄,那么这时我们就可以使用命令 lsof,来查看进程ID和文件句柄了。

注意:文件句柄又叫文件描述符又叫文件号

[devl@xungen ~]$ lsof -c webserver | grep -e 'log$'
webserver  10124  devl  4u  REG 253,1  8814787  109523 /home/devl/application/webserver/log/webserver.00.log

以上的执行结果显示 webserver 服务的进程 ID 为 10124,日志文件句柄为 4u(即 4 号句柄),所以 /proc/10124/fd/4 就是日志文件(webserver.00.log)在 webserver 进程中的内存映射路径,这时你用 tail 命令就可查看日志文件了。

[devl@xungen ~]$ tail -f /proc/10124/fd/4
[20190602 09:51:04|INF] start route ping process success
[20190602 09:51:04|INF] ping host[127.0.0.1:8888][3951] success
[20190602 09:51:09|INF] check session success
[20190602 09:51:09|INF] start route ping process success
[20190602 09:51:09|INF] ping host[127.0.0.1:8888][3596] success
[20190602 09:51:14|INF] start route ping process success
[20190602 09:51:14|INF] ping host[127.0.0.1:8888][3390] success
[20190602 09:51:19|INF] start route ping process success
[20190602 09:51:19|INF] ping host[127.0.0.1:8888][3383] success
[20190602 09:51:19|INF] check session success

扩展知识:

当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。 在 /proc 目录下存储着反映内核和进程树的各种文件。/proc 目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是从内存中获取相关信息。大多数与 lsof 相关的信息都存储于以进程 ID 命名的目录中,例如: /proc/1234 中存储的是 PID 为 1234 的进程的信息。每个进程目录中存储着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。

(三)恢复被删除的文件

当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过 lsof/proc 目录下恢复该文件的内容。 假如,由于误操作将 /var/log/messages 文件删除掉了,那么这时要将 /var/log/messages 文件恢复的方法如下:

首先使用 lsof 来查看当前是否有进程打开 /var/logmessages 文件,如下:

[root@htlwk0001host ~]# lsof |grep /var/log/messages 
syslogd 1283 root 2w REG 3,3 5381017 1773647 /var/log/messages (deleted)

从上面的信息可以看到进程 syslogd(PID=1283)打开文件的文件描述符为 2w。同时还可以看到 /var/log/messages 已经标记被删除了。因此我们可以在 /proc/1283/fd/2 中查看相应的信息,如下:

[root@htlwk0001host ~]# head -n 10 /proc/1283/fd/2 
Aug 4 13:50:15 holmes86 syslogd 1.4.1: restart. 
Aug 4 13:50:15 holmes86 kernel: klogd 1.4.1, log source = /proc/kmsg started. 
Aug 4 13:50:15 holmes86 kernel: Linux version 2.6.22.1-8 (root@everestbuilder.linux-ren.org) (gcc version 4.2.0) 
1 SMP Wed Jul 18 11:18:32 EDT 2007 
Aug 4 13:50:15 holmes86 kernel: BIOS-provided physical RAM map: 
Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000000000 - 000000000009f000 (usable) 
Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved) 
Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000100000 - 000000001f7d3800 (usable) 
Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000001f7d3800 - 0000000020000000 (reserved) 
Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000e0000000 - 00000000f0007000 (reserved) 
Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000f0008000 - 00000000f000c000 (reserved)

如果可以通过文件描述符查看相应的数据,那么就可以使用 I/O 重定向将其复制到文件中,命令语句如下:

[root@htlwk0001host ~]# cat /proc/1283/fd/2 > /var/log/messages

或者

[root@htlwk0001host ~]# sh -c 'cat /proc/1283/fd/2 > /var/log/messages' 

然后修复文件的权限属性并重启 rsyslog 服务:

[root@htlwk0001host ~]# chown messages:adm /var/log/messages
[root@htlwk0001host ~]# systemctl restart rsyslog.service

这样就完成了 /var/log/messages 文件的恢复工作。对于许多应用程序,尤其是日志文件和数据库,这种恢复删除文件的方法非常有用。

(四) 日志文件删除后磁盘空间可用空间没有变大,怎么解决

发现文件系统 /tmp 目录下空间居然用满了,但用 du 命令统计 /tmp 目录中所有文件的大小,发现并没有大文件,怎么回事呢?出现这样的情况,很有可能是被删除的大文件依旧有其它程序在使用,所以依旧占用着磁盘空间,只是我们正常的方式无法查看到此文件,换句话说就是文件没有被彻底删除,这时候我们可以使用命令 lsof 求证下 。

步骤 1:查看系统磁盘的使用情况

[root@htlwk0001host ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 8.6G 1.5G 6.7G 18% /
/dev/sda10 784G 325G 420G 44% /u01
/dev/sda5 8.7G 7.9G 407M 96% /tmp
/dev/sda2 15G 2.8G 11G 21% /usr
/dev/sda1 122M 12M 104M 10% /boot
tmpfs 7.9G 4.0K 7.9G 1% /dev/shm

如上所示,/tmp 可用空剩下 407M

步骤 2:使用命令 lsof 查看正在被进程使用的与 /tmp 相关的文件

[root@htlwk0001host ~]# sudo lsof | grep /tmp
sleep 18833 peien.htg 1w REG 8,5 8321143673 54 /tmp/netstat.log (deleted)
netstat_2 13571 peien.htg 1w REG 8,5 8321143673 54 /tmp/netstat.log (deleted)
tcprstat 18823 root 2w REG 8,5 43632 49 /tmp/myrt.daemon.log
sh 18822 mysql 2w REG 8,5 43632 49 /tmp/myrt.daemon.log
sh 18822 mysql 1w REG 8,5 43632 49 /tmp/myrt.daemon.log
myrt.pl 26045 mysql 2w REG 8,5 43632 49 /tmp/myrt.daemon.log
myrt.pl 26045 mysql 1w REG 8,5 43632 49 /tmp/myrt.daemon.log
check_age 25298 mysql 2w REG 8,5 22049 33 /tmp/check_agent.log
check_age 25298 mysql 1w REG 8,5 22049 33 /tmp/check_agent.log
mysqld 3784 mysql 6u REG 8,5 15156 13 /tmp/ibH3IFN9 (deleted)

如上所示列表中的第二行,文件大小7个多G,文件标记已删,但是依旧被进程“netstat_2”占用,该进程的 PID=13571。

步骤 3: 我们可以使用命令 ps 查看进程更为详细的信息

[root@htlwk0001host ~]# ps -ef | grep 13571
51717 13571 1 0 2011 ? 00:15:00 /bin/bash /tmp/netstat_20110829.sh
51717 21456 13571 0 09:40 ? 00:00:00 sleep 10
zhuxu 21458 17014 0 09:40 pts/0 00:00:00 grep 13571

步骤 4:接着我们将此进程 kill 掉

[root@htlwk0001host ~]# sudo kill -9 13571

步骤 5:然后我们再看看那个已删的文件是否被进程占用着

[root@htlwk0001host ~]# sudo lsof | grep /tmp
tcprstat 22084 root 2w REG 8,5 49339 49 /tmp/myrt.daemon.log
sh 22083 mysql 2w REG 8,5 49339 49 /tmp/myrt.daemon.log
sh 22083 mysql 1w REG 8,5 49339 49 /tmp/myrt.daemon.log
myrt.pl 26045 mysql 2w REG 8,5 49339 49 /tmp/myrt.daemon.log
myrt.pl 26045 mysql 1w REG 8,5 49339 49 /tmp/myrt.daemon.log
check_age 25298 mysql 2w REG 8,5 24583 33 /tmp/check_agent.log
check_age 25298 mysql 1w REG 8,5 24583 33 /tmp/check_agent.log
mysqld 3784 mysql 6u REG 8,5 15156 13 /tmp/ibH3IFN9 (deleted)
su 17013 root cwd DIR 8,5 4096 2 /tmp
sort 22090 zhuxu cwd DIR 8,5 4096 2 /tmp

如上所示结果,看不到那个已删的大文件了。

步骤 6:我们再看看系统磁盘分区的使用情况,确认下 /tmp 的使用空间是否增加了

[root@htlwk0001host ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 8.6G 1.5G 6.7G 18% /
/dev/sda10 784G 325G 420G 44% /u01
/dev/sda5 8.7G 56M 8.2G 1% /tmp
/dev/sda2 15G 2.8G 11G 21% /usr
/dev/sda1 122M 12M 104M 10% /boot
tmpfs 7.9G 4.0K 7.9G 1% /dev/shm

如上所示,目录 /tmp 的可用空间变成 8.2G 了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334502.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mongodb json_在MongoDB和Spring Batch中将XML转换为JSON和原始使用

mongodb json总览 为什么将XML转换为JSON以在MongoDB中原始使用&#xff1f; 由于MongoDB使用JSON文档存储记录&#xff0c;就像表和行将记录存储在关系数据库中一样&#xff0c;我们自然需要将XML转换为JSON。 某些应用程序可能需要存储原始&#xff08;未修改的&#xff09;…

java串口发送16进制数据_MFC串口通信发送16进制数据的方法

本文实例为大家分享了MFC串口通信发送16进制数据的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下MFC串口通信会使用m_mscomm控件。发送数据一般是在edit control 里输入自己想发送的内容&#xff0c;然后点击send button。如果直接发送字符串内容&#xff0c;通过下…

Linux 命令之 du -- 显示每个文件和目录的磁盘使用空间/所占用的磁盘空间大小/所使用的磁盘空间大小/查看文件和目录的大小

文章目录命令介绍常用选项参考示例&#xff08;一&#xff09;显示当前目录下的所有子目录和文件所占空间&#xff08;二&#xff09;查看指定文件所占空间的大小&#xff08;三&#xff09;查看指定目录的所占空间&#xff08;四&#xff09;查看多个文件所占空间&#xff08;…

vue 侦听器侦听对象属性_Spring中的异步和事务性事件侦听器

vue 侦听器侦听对象属性内置的事件发布功能从Spring的早期版本开始存在&#xff0c;并且对于处理同一应用程序上下文中Spring组件之间的基本通信仍然有用。 通常&#xff0c;应用程序可以生成应用程序事件&#xff08;可以是任意对象&#xff09;并监听它们。 整个机制非常简单…

mac tomcat java_Mac下配置Java开发环境(JDK1.8)和Tomcat服务器

平时做PHP,装的有nginx,mysql这儿就不多说了&#xff0c;可以看前面的相关文章&#xff0c;用的brew配置的&#xff0c;超简单。 今天介绍一下Java相关的配置 Java官网下载&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/index.html 我这儿下载的是Java…

python集合和字典的区别_Python中的字典和集合

导语&#xff1a;本文章记录了本人在学习Python基础之数据结构篇的重点知识及个人心得&#xff0c;打算入门Python的朋友们可以来一起学习并交流。 本文重点&#xff1a; 1、掌握常见的字典创建&#xff0c;查询&#xff0c;判别方法&#xff1b; 2、了解字典中的defaultdict、…

Linux 命令之 df -- 显示磁盘空间使用情况

文章目录命令介绍常用选项大小格式参考示例&#xff08;一&#xff09;查看系统磁盘设备的使用情况&#xff08;二&#xff09;显示指定文件所在分区的磁盘使用情况&#xff08;三&#xff09;显示文件类型为ext4的磁盘使用情况命令介绍 df 命令的英文全称即“Disk Free”&…

apache ignite_Apache Ignite本机持久性,简要概述

apache ignite通过将数据的工作集放入系统内存中&#xff0c;内存中方法可以达到极高的速度。 当所有数据都保存在内存中后&#xff0c;就不再需要处理使用传统旋转磁盘引起的问题。 例如&#xff0c;这意味着无需维护数据的其他缓存副本并管理它们之间的同步。 但是这种方法还…

java编程九九乘法表_如何用JAVA语言编写一个九九乘法表

教一下学了JAVA語言的同学们撰写一个99玖玖乘决表方法进行设计构思&#xff1a;假如把99玖玖乘决报表中如“1*11”算式全部当作一个一字的笔画体得话&#xff0c;99玖玖乘决表可当作一个倾斜角二五长方形形&#xff0c;进行倾斜角二五长方形形可用两个for循环系统软件嵌套循环来…

python tkinter 安装_如何为Python安装tkinter?

如果你和我一样&#xff0c;由于你在I.S中的好朋友而在你的网络上没有根目录特权&#xff0c;而且你是在本地安装中工作的&#xff0c;你可能会在上面的方法上遇到一些问题。 我在谷歌上花了很长时间--但最终&#xff0c;这很容易。 要在Linux上本地安装(我将其安装到我的主目录…

Linux 命令之 more -- 显示文本文件内容/显示文件内容/查看文件内容

文章目录一、命令介绍二、常用选项三、命令内部操作快捷键四、参考示例&#xff08;一&#xff09;显示文件file的内容&#xff0c;显示之前先清屏&#xff0c;附已显示的百分比&#xff08;二&#xff09;显示文件file的内容&#xff0c;每10行显示一次&#xff0c;而且在显示…

java jigsaw_Java 9,Jigsaw,JPMS和模块:个人探索

java jigsawJava 9由于Jigsaw项目而延迟了很多次&#xff0c;您可能会听到很多关于模块&#xff0c;模块化和其他内容的信息&#xff0c;那么&#xff0c;这到底是什么呢&#xff1f; 什么是模块化&#xff0c;模块化平台是什么意思&#xff1f; Java平台模块系统&#xff08;J…

java conf_JAVA 解析、编辑nginx.conf详解

最近工程开发遇到一个需求&#xff1a;用Java去解析并编辑nginx.conf解析nginx.conf过程可以参考该项目的README.md下面举个列子说明一下该如何编辑nginx.conf。定义一个pojoimportcom.alibaba.fastjson.JSONArray;importcom.google.common.base.Strings;importlombok.Data;Dat…

mysql explain 为空_车祸现场!我的MySQL千万级数据表选错索引了!

最近在线上环境遇到了一次SQL慢查询引发的数据库故障&#xff0c;影响线上业务。经过排查后&#xff0c;确定原因是&#xff1a;SQL在执行时&#xff0c;MySQL优化器选择了错误的索引(不应该说是“错误”&#xff0c;而是选择了实际执行耗时更长的索引)。排查过程中&#xff0c…

Linux 命令之 head -- 在屏幕上显示指定文件的开头若干行/显示文件开头内容/查看文件开头内容

文章目录命令介绍常用选项参考示例&#xff08;一&#xff09;显示前 3 行文件内容&#xff08;二&#xff09;显示文件名信息&#xff0c;并显示文件前两行&#xff08;三&#xff09;显示文件前5个字符命令介绍 head 命令用于显示文件的开头的内容。在默认情况下&#xff0c…

java登录界面命令_Java命令行界面(第25部分):JCommando

java登录界面命令JCommando 网站 上将JCommando描述为“命令行参数的Java参数解析器”。 JCommando读取XML配置以生成一个Java类&#xff0c;该类处理Java应用程序中的解析。 在提供XML配置的 Java命令行解析库的本系列文章中&#xff0c;以前涵盖的唯一基于Java的库是JSAP &am…

数据追加用什么函数_RL用算法发现算法:DeepMind 数据驱动「价值函数」自我更新,14款Atari游戏完虐人类!...

【新智元导读】击败卡斯帕罗夫的「深蓝」并不是真正的人工智能&#xff0c;它过度依赖了人类设计的规则&#xff0c;而最近DeepMind的一项深度强化学习新研究表明&#xff0c;不用人工介入&#xff0c;完全数据驱动&#xff0c;算法自己就能发现算法。「深蓝」并非以智取胜&…

Linux 命令之 tail -- 在屏幕上显示指定文件的末尾若干行/显示文件尾部内容/查看文件尾部内容

文章目录一、命令介绍二、常用选项三、参考示例&#xff08;一&#xff09;显示文件 file 的最后 10 行&#xff08;二&#xff09;显示文件 file 的内容&#xff0c;从第 20 行至文件末尾&#xff08;三&#xff09;显示文件file的最后10个字符&#xff08;四&#xff09;显示…

python的循环语句机制_Python-for循环的内部机制

Python中&#xff0c;使用for循环可以迭代容器对象中的元素&#xff0c;这里容器对象包括是列表(list)、元组(tuple)、字典(dict)、集合(set)等。但是&#xff0c;为什么这些对象可以使用for循环进行操作呢&#xff1f;首先&#xff0c;定义一个简单的类尝试一下&#xff1a;cl…

迈克尔 杰克逊mv_用杰克逊流式传输大型JSON文件– RxJava常见问题解答

迈克尔 杰克逊mv在上一篇文章中&#xff0c;我们学习了如何解析过大的XML文件并将其转换为RxJava流。 这次让我们看一个大的JSON文件。 我们的示例将基于微小的colors.json&#xff0c;其中包含将近150种这种格式的记录&#xff1a; {"aliceblue": [240, 248, 255, …