zhcn 技术 手机 在 Linux 上使用 lsof 命令的示例

在 Linux 上使用 lsof 命令的示例

lsof 是一个功能强大的实用程序,可在 Linux 和基于 Unix 的系统上使用,字面意思是“打开文件列表”。

它的主要功能是获取不同运行进程打开的不同类型文件的详细信息。这些文件包括常规文件、目录、块文件、网络套接字、命名管道等。

您可以使用lsof找出对文件或目录具有锁定的不同进程、哪些进程正在侦听端口、用户的进程列表以及该进程具有锁定的所有文件。本文首先介绍安装,然后介绍一些常见用例

安装lof

lsof在大多数 Linux 发行版上默认不可用,但可以轻松安装。使用以下命令安装 lsof。

CentOS/RHEL/Fedora:

 $ sudo yum install lsof

对于 CentOS/RHEL 8,您可以使用 DNF 命令。

 $ sudo dnf install lsof

Ubuntu/Debian:

 $ sudo apt install lsof

求人

您可以使用-?获取 lsof 支持的选项的精简列表。或-h标志。

 $ lsof -?
lsof 4.87
 latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
 latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
 latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
 usage: [-?abhKlnNoOPRtUvVX] [+|-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]] [-Z [Z]] [--] [names]
Defaults in parentheses; comma-separated set (s) items; dash-separated ranges.
  -?|-h list help          -a AND selections (OR)     -b avoid kernel blocks
  -c c  cmd c ^c /c/[bix]  +c w  COMMAND width (9)    +d s  dir s files
  -d s  select by FD set   +D D  dir D tree *SLOW?*   +|-e s  exempt s *RISKY*
  -i select IPv[46] files  -K list tasKs (threads)    -l list UID numbers
  -n no host names         -N select NFS files        -o list file offset
  -O no overhead *RISKY*   -P no port names           -R list paRent PID
  -s list file size        -t terse listing           -T disable TCP/TPI info
  -U select Unix socket    -v list version info       -V verbose search
  +|-w  Warnings (+)       -X skip TCP&UDP* files     -Z Z  context [Z]
  -- end option scan
  +f|-f  +filesystem or -file names     +|-f[gG] flaGs
  -F [f] select fields; -F? for help
  +|-L [l] list (+) suppress (-) link counts < l (0 = all; default = 0)
                                        +m [m] use|create mount supplement
  +|-M   portMap registration (-)       -o o   o 0t offset digits (8)
  -p s   exclude(^)|select PIDs         -S [t] t second stat timeout (15)
  -T qs TCP/TPI Q,St (s) info
  -g [s] exclude(^)|select and print process group IDs
  -i i   select by IPv[46] address: [46][proto][@host|addr][:svc_list|port_list]
  +|-r [t[m<fmt>]] repeat every t seconds (15);  + until no files, - forever.
       An optional suffix to t is m<fmt>; m must separate t from <fmt> and
      <fmt> is an strftime(3) format for the marker line.
  -s p:s  exclude(^)|select protocol (p = TCP|UDP) states by name(s).
  -u s   exclude(^)|select login|UID set s
  -x [fl] cross over +d|+D File systems or symbolic Links
  names  select named files or files on named file systems
Anyone can list all files; /dev warnings disabled; kernel ID check disabled.
$

要查看有关已安装版本的详细信息,请使用:

 $ lsof -v
lsof version information:
    revision: 4.87
    latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
    latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
    latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
    constructed: Tue Oct 30 16:28:19 UTC 2018
    constructed by and on: mockbuild@x86-01.bsys.centos.org
    compiler: cc
    compiler version: 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
    compiler flags: -DLINUXV=310000 -DGLIBCV=217 -DHASIPv6 -DHASSELINUX -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHAS_STRFTIME -DLSOF_VSTR="3.10.0" -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic
    loader flags: -L./lib -llsof  -lselinux
    system info: Linux x86-01.bsys.centos.org 3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
    Anyone can list all files.
    /dev warnings are disabled.
    Kernel ID check is disabled.
$

输出字段

默认的 lsof 输出字段结构如下所示:

 COMMAND    PID  TID         USER   FD      TYPE DEVICE  SIZE/OFF     NODE NAME

这些字段中的大多数都是不言自明的,但FDTYPE字段除外,它们在某种程度上是 lsof 所特有的,因此我们将简要介绍它们。

TYPEFD文件的文件描述符号,指与该文件关联的节点类型。现在检查这两个字段支持的值。

FD字段可以包含以下值:

 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;

FD字段后跟一个或多个字符,描述文件打开的模式。

 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.

FD模式字符后面可以跟有如下所述的LOCK字符。

 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字段可以包含GDIR, GREG, VDIR, VREG, IPV4, IPV6等。要获取 lsof 支持的TYPE的完整列表,请参阅其man页。

常见用法

以下是 lsof 命令的一些常见用法。此命令适用于各种版本的 Linux,并且考虑到相同lsof版本,下面示例中列出的所有命令行参数都应适用于所有平台。

在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

列出所有打开的文件

不带任何选项运行 lsof 会列出当前由活动进程打开的所有文件。

 $ sudo lsof | less

输出:

 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   1632776     308905 /usr/lib/systemd/systemd
systemd      1              root  mem       REG              253,0     20064      16063 /usr/lib64/libuuid.so.1.3.0
systemd      1              root  mem       REG              253,0    265576     186547 /usr/lib64/libblkid.so.1.1.0
systemd      1              root  mem       REG              253,0     90248      16051 /usr/lib64/libz.so.1.2.7
systemd      1              root  mem       REG              253,0    157424      16059 /usr/lib64/liblzma.so.5.2.2
systemd      1              root  mem       REG              253,0     23968      59696 /usr/lib64/libcap-ng.so.0.0.0
systemd      1              root  mem       REG              253,0     19896      59686 /usr/lib64/libattr.so.1.1.0
systemd      1              root  mem       REG              253,0     19248      15679 /usr/lib64/libdl-2.17.so
systemd      1              root  mem       REG              253,0    402384      16039 /usr/lib64/libpcre.so.1.2.0
systemd      1              root  mem       REG              253,0   2156272      15673 /usr/lib64/libc-2.17.so
systemd      1              root  mem       REG              253,0    142144      15699 /usr/lib64/libpthread-2.17.so
systemd      1              root  mem       REG              253,0     88720         84 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
systemd      1              root  mem       REG              253,0     43712      15703 /usr/lib64/librt-2.17.so
systemd      1              root  mem       REG              253,0    277808     229793 /usr/lib64/libmount.so.1.1.0
systemd      1              root  mem       REG              253,0     91800      76005 /usr/lib64/libkmod.so.2.2.10
systemd      1              root  mem       REG              253,0    127184      59698 /usr/lib64/libaudit.so.1.0.0
systemd      1              root  mem       REG              253,0     61680     229827 /usr/lib64/libpam.so.0.83.1
systemd      1              root  mem       REG              253,0     20048      59690 /usr/lib64/libcap.so.2.22
systemd      1              root  mem       REG              253,0    155744      16048 /usr/lib64/libselinux.so.1 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按文件名列出

要列出已打开特定文件的所有进程,请将file-name指定为参数。

 $ sudo lsof {file-name}

输出:

 $ sudo lsof /var/log/messages
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
rsyslogd 1000 root    6w   REG  253,0      205 16777741 /var/log/messages
$ 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按用户名列出打开的文件

在多用户系统上,您可以使用-u标志后跟username来按特定用户拥有的进程过滤文件列表。

 $ sudo lsof -u {username}

输出:

 $ sudo lsof -u abhisheknair
COMMAND  PID         USER   FD   TYPE             DEVICE  SIZE/OFF     NODE NAME
sshd    1239 abhisheknair  cwd    DIR              253,0       224       64 /
sshd    1239 abhisheknair  rtd    DIR              253,0       224       64 /
sshd    1239 abhisheknair  txt    REG              253,0    852856   425229 /usr/sbin/sshd
sshd    1239 abhisheknair  mem    REG              253,0     15488 17204727 /usr/lib64/security/pam_lastlog.so
sshd    1239 abhisheknair  mem    REG              253,0     15648   229829 /usr/lib64/libpam_misc.so.0.82.0
sshd    1239 abhisheknair  mem    REG              253,0    309248 17303270 /usr/lib64/security/pam_systemd.so
sshd    1239 abhisheknair  mem    REG              253,0     19616 17204728 /usr/lib64/security/pam_limits.so
sshd    1239 abhisheknair  mem    REG              253,0     11168 17204726 /usr/lib64/security/pam_keyinit.so
sshd    1239 abhisheknair  mem    REG              253,0     40800 17204735 /usr/lib64/security/pam_namespace.so

或者,如果要列出除特定用户之外的任何用户打开的文件,请使用-u标志,后跟^username如下所示。

 $ sudo lsof -u ^{username}

输出:

 $ sudo lsof -u ^root
COMMAND    PID TID         USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
dbus-daem  630             dbus  cwd       DIR              253,0       224       64 /
dbus-daem  630             dbus  rtd       DIR              253,0       224       64 /
dbus-daem  630             dbus  txt       REG              253,0    223232 50590133 /usr/bin/dbus-daemon
dbus-daem  630             dbus  mem       REG              253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
dbus-daem  630             dbus  mem       REG              253,0     68192    59651 /usr/lib64/libbz2.so.1.0.6
dbus-daem  630             dbus  mem       REG              253,0     90248    16051 /usr/lib64/libz.so.1.2.7
dbus-daem  630             dbus  mem       REG              253,0     99944    59680 /usr/lib64/libelf-0.176.so
dbus-daem  630             dbus  mem       REG              253,0     19896    59686 /usr/lib64/libattr.so.1.1.0
dbus-daem  630             dbus  mem       REG              253,0    402384    16039 /usr/lib64/libpcre.so.1.2.0

使用 lsof 的一种方法是使用单个命令快速终止特定用户的所有进程。您可以通过组合killlsof来实现此目的,如下例所示(以 root 身份运行):

 # kill -9 `lsof -t -u {username}`

如上面的示例所示,您可以使用-t标志排除除process-id之外的所有其他信息。这对于与kill命令结合使用的自动化和脚本编写非常有用,如前面的示例所示。

 $ sudo lsof -t -u {username}

输出:

 $ sudo lsof -t -u abhisheknair
1239
1240
$

lsof 允许您使用OR逻辑组合多个参数,如下所示。

 $ sudo lsof -u {username} -c {process-name}

输出:

 $ sudo lsof -u ftpuser -c bash
COMMAND  PID         USER   FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1240 abhisheknair  cwd    DIR  253,0       120   510681 /home/abhisheknair
bash    1240 abhisheknair  rtd    DIR  253,0       224       64 /
bash    1240 abhisheknair  txt    REG  253,0    964536 50548532 /usr/bin/bash
bash    1240 abhisheknair  mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
bash    1240 abhisheknair  mem    REG  253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
bash    1240 abhisheknair  mem    REG  253,0   2156272    15673 /usr/lib64/libc-2.17.so
bash    1240 abhisheknair  mem    REG  253,0     19248    15679 /usr/lib64/libdl-2.17.so
bash    1240 abhisheknair  mem    REG  253,0    174576    16034 /usr/lib64/libtinfo.so.5.9
bash    1240 abhisheknair  mem    REG  253,0    163312    15666 /usr/lib64/ld-2.17.so
bash    1240 abhisheknair  mem    REG  253,0     26970    16003 /usr/lib64/gconv/gconv-modules.cache
bash    1240 abhisheknair    0u   CHR  136,0       0t0        3 /dev/pts/0
bash    1240 abhisheknair    1u   CHR  136,0       0t0        3 /dev/pts/0
bash    1240 abhisheknair    2u   CHR  136,0       0t0        3 /dev/pts/0
bash    1240 abhisheknair  255u   CHR  136,0       0t0        3 /dev/pts/0
bash    1425      ftpuser  cwd    DIR  253,0       182 33578272 /home/ftpuser
bash    1425      ftpuser  rtd    DIR  253,0       224       64 /
bash    1425      ftpuser  txt    REG  253,0    964536 50548532 /usr/bin/bash
bash    1425      ftpuser  mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
bash    1425      ftpuser  mem    REG  253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
bash    1425      ftpuser  mem    REG  253,0   2156272    15673 /usr/lib64/libc-2.17.so
bash    1425      ftpuser  mem    REG  253,0     19248    15679 /usr/lib64/libdl-2.17.so
bash    1425      ftpuser  mem    REG  253,0    174576    16034 /usr/lib64/libtinfo.so.5.9
bash    1425      ftpuser  mem    REG  253,0    163312    15666 /usr/lib64/ld-2.17.so
bash    1425      ftpuser  mem    REG  253,0     26970    16003 /usr/lib64/gconv/gconv-modules.cache
bash    1425      ftpuser    0u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425      ftpuser    1u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425      ftpuser    2u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425      ftpuser  255u   CHR    4,1       0t0     1043 /dev/tty1
$

或者,如果您想使用AND逻辑条件,请使用-a标志。

 $ sudo lsof -u {username} -c {process-name} -a

输出:

 $ sudo lsof -u ftpuser -c bash -a
COMMAND  PID    USER   FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser  cwd    DIR  253,0       182 33578272 /home/ftpuser
bash    1425 ftpuser  rtd    DIR  253,0       224       64 /
bash    1425 ftpuser  txt    REG  253,0    964536 50548532 /usr/bin/bash
bash    1425 ftpuser  mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
bash    1425 ftpuser  mem    REG  253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
bash    1425 ftpuser  mem    REG  253,0   2156272    15673 /usr/lib64/libc-2.17.so
bash    1425 ftpuser  mem    REG  253,0     19248    15679 /usr/lib64/libdl-2.17.so
bash    1425 ftpuser  mem    REG  253,0    174576    16034 /usr/lib64/libtinfo.so.5.9
bash    1425 ftpuser  mem    REG  253,0    163312    15666 /usr/lib64/ld-2.17.so
bash    1425 ftpuser  mem    REG  253,0     26970    16003 /usr/lib64/gconv/gconv-modules.cache
bash    1425 ftpuser    0u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425 ftpuser    1u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425 ftpuser    2u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425 ftpuser  255u   CHR    4,1       0t0     1043 /dev/tty1
$ 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按进程列出打开的文件

您还可以使用-c选项后跟进程名称来列出特定进程打开的文件。

 $ sudo lsof -c {process-name}

输出:

 $ sudo lsof -c ssh
COMMAND  PID         USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
sshd     997         root  cwd    DIR              253,0      224       64 /
sshd     997         root  rtd    DIR              253,0      224       64 /
sshd     997         root  txt    REG              253,0   852856   425229 /usr/sbin/sshd
sshd     997         root  mem    REG              253,0    61560    15691 /usr/lib64/libnss_files-2.17.so
sshd     997         root  mem    REG              253,0    68192    59651 /usr/lib64/libbz2.so.1.0.6
sshd     997         root  mem    REG              253,0    99944    59680 /usr/lib64/libelf-0.176.so
sshd     997         root  mem    REG              253,0    19896    59686 /usr/lib64/libattr.so.1.1.0
sshd     997         root  mem    REG              253,0    15688    75906 /usr/lib64/libkeyutils.so.1.5
sshd     997         root  mem    REG              253,0    67104   186525 /usr/lib64/libkrb5support.so.0.1 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按 PID 列出打开的文件

或者,要列出进程打开的文件,但指定其 ID 而不是process-name ,请使用-p标志,后跟process-id

 $ sudo lsof -p {process-id}

输出:

 $ sudo lsof -p 663
COMMAND   PID USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
firewalld 663 root  cwd       DIR              253,0       224       64 /
firewalld 663 root  rtd       DIR              253,0       224       64 /
firewalld 663 root  txt       REG              253,0      7144 50491220 /usr/bin/python2.7
firewalld 663 root  mem       REG              253,0    298828 50617647 /usr/lib64/girepository-1.0/NM-1.0.typelib
firewalld 663 root  mem       REG              253,0    343452 50507562 /usr/lib64/girepository-1.0/Gio-2.0.typelib
firewalld 663 root  mem       REG              253,0     12352 17202092 /usr/lib64/python2.7/lib-dynload/grpmodule.so
firewalld 663 root  mem       REG              253,0     29184 17202105 /usr/lib64/python2.7/lib-dynload/selectmodule.so
firewalld 663 root  mem       REG              253,0    168312   388240 /usr/lib64/libdbus-glib-1.so.2.2.2
firewalld 663 root  mem       REG              253,0     11976 34028597 /usr/lib64/python2.7/site-packages/_dbus_glib_bindings.so
firewalld 663 root  mem       REG              253,0    185712 50507559 /usr/lib64/girepository-1.0/GLib-2.0.typelib
  • 如果要列出所有打开的文件(不包括特定进程打开的文件),请使用-p后跟^process-id
 $ sudo lsof -p ^{process-id}

列出打开的文件,包括目录

要列出已打开特定目录下的文件的进程,请使用+D选项,后跟目录路径。

 $ sudo lsof +D {path}

输出:

 $ sudo lsof +D /var/log
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
auditd     607 root    5w   REG  253,0  1065095   425227 /var/log/audit/audit.log
firewalld  663 root    3w   REG  253,0    13817 17663786 /var/log/firewalld
tuned      999 root    3w   REG  253,0    13395 33574994 /var/log/tuned/tuned.log
rsyslogd  1000 root    6w   REG  253,0     4302 16777753 /var/log/cron
rsyslogd  1000 root    7w   REG  253,0    64740 16777755 /var/log/messages
rsyslogd  1000 root    8w   REG  253,0     5513 16787904 /var/log/secure
rsyslogd  1000 root    9w   REG  253,0      198 16777754 /var/log/maillog
$

如果您不想递归地列出子目录中的文件,请使用-d标志,后跟目录路径。

 $ sudo lsof +d {path}

输出:

 $ sudo lsof +d /var/log
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
firewalld  663 root    3w   REG  253,0    13817 17663786 /var/log/firewalld
rsyslogd  1000 root    6w   REG  253,0     4302 16777753 /var/log/cron
rsyslogd  1000 root    7w   REG  253,0    64740 16777755 /var/log/messages
rsyslogd  1000 root    8w   REG  253,0     5833 16787904 /var/log/secure
rsyslogd  1000 root    9w   REG  253,0      198 16777754 /var/log/maillog
$

重复模式

lsof 可以在重复模式下运行。在重复模式下,lsof 定期生成并打印输出。同样,lsof 使用-r+r标志支持两种重复模式。 -r标志使 lsof 重复执行,直到收到用户的中断/终止信号,而+r标志使 lsof 在输出中没有打开的文件时立即退出重复模式。此外,您可以使用-r+r标志指定延迟时间。

 $ sudo lsof {arguments} -r{time-interval}

输出:

 $ sudo lsof -u ftpuser -c bash +D /usr/lib -a -r3
COMMAND  PID    USER  FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
=======
COMMAND  PID    USER  FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
=======
COMMAND  PID    USER  FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
=======

使用网络协议列出打开的文件

lsof 支持列出所有类型的 Linux 文件,包括网络套接字等。因此,您可以使用-i标志列出打开的网络连接的详细信息。

 $ sudo lsof -i

输出:

 $ sudo lsof -i
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd  639       chrony    5u  IPv4  14333      0t0  UDP localhost:323
chronyd  639       chrony    6u  IPv6  14334      0t0  UDP localhost:323
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
master  1229         root   13u  IPv4  18129      0t0  TCP localhost:smtp (LISTEN)
master  1229         root   14u  IPv6  18130      0t0  TCP localhost:smtp (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

要列出特定process-id使用的所有网络连接,您可以使用 lsof,如下所示:

 $ sudo lsof -i -a -p {process-id}

输出:

 $ sudo lsof -i -a -p 997
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    997 root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd    997 root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
$

或者,要列出特定进程使用的所有网络连接,请指定process-name如下所示:

 $ sudo lsof -i -a -c {process-name}

输出:

 $ sudo lsof -i -a -c ssh
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

您可以使用-i标志按网络协议类型(即通过指定协议类型来过滤TCPUDP lsof 的输出。

 $ sudo lsof -i {protocol}

输出:

 $ sudo lsof -i tcp
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
master  1229         root   13u  IPv4  18129      0t0  TCP localhost:smtp (LISTEN)
master  1229         root   14u  IPv6  18130      0t0  TCP localhost:smtp (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

或者

输出:

 $ sudo lsof -i udp
COMMAND PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd 639 chrony    5u  IPv4  14333      0t0  UDP localhost:323
chronyd 639 chrony    6u  IPv6  14334      0t0  UDP localhost:323
$

按端口列出打开的文件

您还可以使用-i标志使用以下命令语法按port number过滤 lsof 的输出。

 $ sudo lsof -i :{port-number}

输出:

 $ sudo lsof -i :22
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

按 IPv4/IPv6 列出打开的文件

有一个选项可以将网络连接列表限制和过滤为 IPv4 或 IPv6。要仅获取 IPv4 列表,请使用以下命令语法:

 $ sudo lsof -i4

输出:

 $ sudo lsof -i4
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd  639       chrony    5u  IPv4  14333      0t0  UDP localhost:323
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
master  1229         root   13u  IPv4  18129      0t0  TCP localhost:smtp (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

或者要仅获取 IPv6 详细信息,请使用:

 $ sudo lsof -i6

输出:

 $ sudo lsof -i6
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd  639 chrony    6u  IPv6  14334      0t0  UDP localhost:323
sshd     997   root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
master  1229   root   14u  IPv6  18130      0t0  TCP localhost:smtp (LISTEN)
$

列出 NFS 上打开的文件

lsof 还可以列出用户当前打开的所有 NFS 文件。

 $ sudo lsof -N -u abhisheknair -a

列出锁定和删除的文件

即使文件已在 Linux 上删除,它也可能仍被一个或多个进程锁定。因此,这些文件不会出现在使用ls命令等的常规文件系统列表中,但它们仍然消耗磁盘空间,如df输出中报告的那样。这种情况尤其发生在故意删除大文件以清理磁盘空间而不释放进程锁的情况下。您可以使用 lsof 找到此类进程,如下所示:

 $ sudo lsof {path} | grep deleted

输出:

 $ sudo lsof / | grep deleted
firewalld  654         root    8u   REG  253,0      4096 16777726 /tmp/#16777726 (deleted)
tuned      968         root    8u   REG  253,0      4096 16777720 /tmp/#16777720 (deleted)
$

结论

lsof 提供了各种选项来根据您的需要自定义输出。对于日常系统和网络管理任务来说,这是一个有用的实用程序。您可以组合不同的参数,这使其更加有用,并且更容易获得您想要的输出。有关所有支持的参数及其用法,请参阅 lsof 手册页。

 $ man lsof

lsof 是一个功能强大的实用程序,可在 Linux 和基于 Unix 的系统上使用,字面意思是“打开文件列表”。

它的主要功能是获取不同运行进程打开的不同类型文件的详细信息。这些文件包括常规文件、目录、块文件、网络套接字、命名管道等。

您可以使用lsof找出对文件或目录具有锁定的不同进程、哪些进程正在侦听端口、用户的进程列表以及该进程具有锁定的所有文件。本文首先介绍安装,然后介绍一些常见用例

安装lof

lsof在大多数 Linux 发行版上默认不可用,但可以轻松安装。使用以下命令安装 lsof。

CentOS/RHEL/Fedora:

 $ sudo yum install lsof

对于 CentOS/RHEL 8,您可以使用 DNF 命令。

 $ sudo dnf install lsof

Ubuntu/Debian:

 $ sudo apt install lsof

求人

您可以使用-?获取 lsof 支持的选项的精简列表。或-h标志。

 $ lsof -?
lsof 4.87
 latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
 latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
 latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
 usage: [-?abhKlnNoOPRtUvVX] [+|-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]] [-Z [Z]] [--] [names]
Defaults in parentheses; comma-separated set (s) items; dash-separated ranges.
  -?|-h list help          -a AND selections (OR)     -b avoid kernel blocks
  -c c  cmd c ^c /c/[bix]  +c w  COMMAND width (9)    +d s  dir s files
  -d s  select by FD set   +D D  dir D tree *SLOW?*   +|-e s  exempt s *RISKY*
  -i select IPv[46] files  -K list tasKs (threads)    -l list UID numbers
  -n no host names         -N select NFS files        -o list file offset
  -O no overhead *RISKY*   -P no port names           -R list paRent PID
  -s list file size        -t terse listing           -T disable TCP/TPI info
  -U select Unix socket    -v list version info       -V verbose search
  +|-w  Warnings (+)       -X skip TCP&UDP* files     -Z Z  context [Z]
  -- end option scan
  +f|-f  +filesystem or -file names     +|-f[gG] flaGs
  -F [f] select fields; -F? for help
  +|-L [l] list (+) suppress (-) link counts < l (0 = all; default = 0)
                                        +m [m] use|create mount supplement
  +|-M   portMap registration (-)       -o o   o 0t offset digits (8)
  -p s   exclude(^)|select PIDs         -S [t] t second stat timeout (15)
  -T qs TCP/TPI Q,St (s) info
  -g [s] exclude(^)|select and print process group IDs
  -i i   select by IPv[46] address: [46][proto][@host|addr][:svc_list|port_list]
  +|-r [t[m<fmt>]] repeat every t seconds (15);  + until no files, - forever.
       An optional suffix to t is m<fmt>; m must separate t from <fmt> and
      <fmt> is an strftime(3) format for the marker line.
  -s p:s  exclude(^)|select protocol (p = TCP|UDP) states by name(s).
  -u s   exclude(^)|select login|UID set s
  -x [fl] cross over +d|+D File systems or symbolic Links
  names  select named files or files on named file systems
Anyone can list all files; /dev warnings disabled; kernel ID check disabled.
$

要查看有关已安装版本的详细信息,请使用:

 $ lsof -v
lsof version information:
    revision: 4.87
    latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
    latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
    latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
    constructed: Tue Oct 30 16:28:19 UTC 2018
    constructed by and on: mockbuild@x86-01.bsys.centos.org
    compiler: cc
    compiler version: 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
    compiler flags: -DLINUXV=310000 -DGLIBCV=217 -DHASIPv6 -DHASSELINUX -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DHAS_STRFTIME -DLSOF_VSTR="3.10.0" -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic
    loader flags: -L./lib -llsof  -lselinux
    system info: Linux x86-01.bsys.centos.org 3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
    Anyone can list all files.
    /dev warnings are disabled.
    Kernel ID check is disabled.
$

输出字段

默认的 lsof 输出字段结构如下所示:

 COMMAND    PID  TID         USER   FD      TYPE DEVICE  SIZE/OFF     NODE NAME

这些字段中的大多数都是不言自明的,但FDTYPE字段除外,它们在某种程度上是 lsof 所特有的,因此我们将简要介绍它们。

TYPEFD文件的文件描述符号,指与该文件关联的节点类型。现在检查这两个字段支持的值。

FD字段可以包含以下值:

 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;

FD字段后跟一个或多个字符,描述文件打开的模式。

 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.

FD模式字符后面可以跟有如下所述的LOCK字符。

 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字段可以包含GDIR, GREG, VDIR, VREG, IPV4, IPV6等。要获取 lsof 支持的TYPE的完整列表,请参阅其man页。

常见用法

以下是 lsof 命令的一些常见用法。此命令适用于各种版本的 Linux,并且考虑到相同lsof版本,下面示例中列出的所有命令行参数都应适用于所有平台。

在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

列出所有打开的文件

不带任何选项运行 lsof 会列出当前由活动进程打开的所有文件。

 $ sudo lsof | less

输出:

 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   1632776     308905 /usr/lib/systemd/systemd
systemd      1              root  mem       REG              253,0     20064      16063 /usr/lib64/libuuid.so.1.3.0
systemd      1              root  mem       REG              253,0    265576     186547 /usr/lib64/libblkid.so.1.1.0
systemd      1              root  mem       REG              253,0     90248      16051 /usr/lib64/libz.so.1.2.7
systemd      1              root  mem       REG              253,0    157424      16059 /usr/lib64/liblzma.so.5.2.2
systemd      1              root  mem       REG              253,0     23968      59696 /usr/lib64/libcap-ng.so.0.0.0
systemd      1              root  mem       REG              253,0     19896      59686 /usr/lib64/libattr.so.1.1.0
systemd      1              root  mem       REG              253,0     19248      15679 /usr/lib64/libdl-2.17.so
systemd      1              root  mem       REG              253,0    402384      16039 /usr/lib64/libpcre.so.1.2.0
systemd      1              root  mem       REG              253,0   2156272      15673 /usr/lib64/libc-2.17.so
systemd      1              root  mem       REG              253,0    142144      15699 /usr/lib64/libpthread-2.17.so
systemd      1              root  mem       REG              253,0     88720         84 /usr/lib64/libgcc_s-4.8.5-20150702.so.1
systemd      1              root  mem       REG              253,0     43712      15703 /usr/lib64/librt-2.17.so
systemd      1              root  mem       REG              253,0    277808     229793 /usr/lib64/libmount.so.1.1.0
systemd      1              root  mem       REG              253,0     91800      76005 /usr/lib64/libkmod.so.2.2.10
systemd      1              root  mem       REG              253,0    127184      59698 /usr/lib64/libaudit.so.1.0.0
systemd      1              root  mem       REG              253,0     61680     229827 /usr/lib64/libpam.so.0.83.1
systemd      1              root  mem       REG              253,0     20048      59690 /usr/lib64/libcap.so.2.22
systemd      1              root  mem       REG              253,0    155744      16048 /usr/lib64/libselinux.so.1 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按文件名列出

要列出已打开特定文件的所有进程,请将file-name指定为参数。

 $ sudo lsof {file-name}

输出:

 $ sudo lsof /var/log/messages
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
rsyslogd 1000 root    6w   REG  253,0      205 16777741 /var/log/messages
$ 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按用户名列出打开的文件

在多用户系统上,您可以使用-u标志后跟username来按特定用户拥有的进程过滤文件列表。

 $ sudo lsof -u {username}

输出:

 $ sudo lsof -u abhisheknair
COMMAND  PID         USER   FD   TYPE             DEVICE  SIZE/OFF     NODE NAME
sshd    1239 abhisheknair  cwd    DIR              253,0       224       64 /
sshd    1239 abhisheknair  rtd    DIR              253,0       224       64 /
sshd    1239 abhisheknair  txt    REG              253,0    852856   425229 /usr/sbin/sshd
sshd    1239 abhisheknair  mem    REG              253,0     15488 17204727 /usr/lib64/security/pam_lastlog.so
sshd    1239 abhisheknair  mem    REG              253,0     15648   229829 /usr/lib64/libpam_misc.so.0.82.0
sshd    1239 abhisheknair  mem    REG              253,0    309248 17303270 /usr/lib64/security/pam_systemd.so
sshd    1239 abhisheknair  mem    REG              253,0     19616 17204728 /usr/lib64/security/pam_limits.so
sshd    1239 abhisheknair  mem    REG              253,0     11168 17204726 /usr/lib64/security/pam_keyinit.so
sshd    1239 abhisheknair  mem    REG              253,0     40800 17204735 /usr/lib64/security/pam_namespace.so

或者,如果要列出除特定用户之外的任何用户打开的文件,请使用-u标志,后跟^username如下所示。

 $ sudo lsof -u ^{username}

输出:

 $ sudo lsof -u ^root
COMMAND    PID TID         USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
dbus-daem  630             dbus  cwd       DIR              253,0       224       64 /
dbus-daem  630             dbus  rtd       DIR              253,0       224       64 /
dbus-daem  630             dbus  txt       REG              253,0    223232 50590133 /usr/bin/dbus-daemon
dbus-daem  630             dbus  mem       REG              253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
dbus-daem  630             dbus  mem       REG              253,0     68192    59651 /usr/lib64/libbz2.so.1.0.6
dbus-daem  630             dbus  mem       REG              253,0     90248    16051 /usr/lib64/libz.so.1.2.7
dbus-daem  630             dbus  mem       REG              253,0     99944    59680 /usr/lib64/libelf-0.176.so
dbus-daem  630             dbus  mem       REG              253,0     19896    59686 /usr/lib64/libattr.so.1.1.0
dbus-daem  630             dbus  mem       REG              253,0    402384    16039 /usr/lib64/libpcre.so.1.2.0

使用 lsof 的一种方法是使用单个命令快速终止特定用户的所有进程。您可以通过组合killlsof来实现此目的,如下例所示(以 root 身份运行):

 # kill -9 `lsof -t -u {username}`

如上面的示例所示,您可以使用-t标志排除除process-id之外的所有其他信息。这对于与kill命令结合使用的自动化和脚本编写非常有用,如前面的示例所示。

 $ sudo lsof -t -u {username}

输出:

 $ sudo lsof -t -u abhisheknair
1239
1240
$

lsof 允许您使用OR逻辑组合多个参数,如下所示。

 $ sudo lsof -u {username} -c {process-name}

输出:

 $ sudo lsof -u ftpuser -c bash
COMMAND  PID         USER   FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1240 abhisheknair  cwd    DIR  253,0       120   510681 /home/abhisheknair
bash    1240 abhisheknair  rtd    DIR  253,0       224       64 /
bash    1240 abhisheknair  txt    REG  253,0    964536 50548532 /usr/bin/bash
bash    1240 abhisheknair  mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
bash    1240 abhisheknair  mem    REG  253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
bash    1240 abhisheknair  mem    REG  253,0   2156272    15673 /usr/lib64/libc-2.17.so
bash    1240 abhisheknair  mem    REG  253,0     19248    15679 /usr/lib64/libdl-2.17.so
bash    1240 abhisheknair  mem    REG  253,0    174576    16034 /usr/lib64/libtinfo.so.5.9
bash    1240 abhisheknair  mem    REG  253,0    163312    15666 /usr/lib64/ld-2.17.so
bash    1240 abhisheknair  mem    REG  253,0     26970    16003 /usr/lib64/gconv/gconv-modules.cache
bash    1240 abhisheknair    0u   CHR  136,0       0t0        3 /dev/pts/0
bash    1240 abhisheknair    1u   CHR  136,0       0t0        3 /dev/pts/0
bash    1240 abhisheknair    2u   CHR  136,0       0t0        3 /dev/pts/0
bash    1240 abhisheknair  255u   CHR  136,0       0t0        3 /dev/pts/0
bash    1425      ftpuser  cwd    DIR  253,0       182 33578272 /home/ftpuser
bash    1425      ftpuser  rtd    DIR  253,0       224       64 /
bash    1425      ftpuser  txt    REG  253,0    964536 50548532 /usr/bin/bash
bash    1425      ftpuser  mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
bash    1425      ftpuser  mem    REG  253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
bash    1425      ftpuser  mem    REG  253,0   2156272    15673 /usr/lib64/libc-2.17.so
bash    1425      ftpuser  mem    REG  253,0     19248    15679 /usr/lib64/libdl-2.17.so
bash    1425      ftpuser  mem    REG  253,0    174576    16034 /usr/lib64/libtinfo.so.5.9
bash    1425      ftpuser  mem    REG  253,0    163312    15666 /usr/lib64/ld-2.17.so
bash    1425      ftpuser  mem    REG  253,0     26970    16003 /usr/lib64/gconv/gconv-modules.cache
bash    1425      ftpuser    0u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425      ftpuser    1u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425      ftpuser    2u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425      ftpuser  255u   CHR    4,1       0t0     1043 /dev/tty1
$

或者,如果您想使用AND逻辑条件,请使用-a标志。

 $ sudo lsof -u {username} -c {process-name} -a

输出:

 $ sudo lsof -u ftpuser -c bash -a
COMMAND  PID    USER   FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser  cwd    DIR  253,0       182 33578272 /home/ftpuser
bash    1425 ftpuser  rtd    DIR  253,0       224       64 /
bash    1425 ftpuser  txt    REG  253,0    964536 50548532 /usr/bin/bash
bash    1425 ftpuser  mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
bash    1425 ftpuser  mem    REG  253,0     61560    15691 /usr/lib64/libnss_files-2.17.so
bash    1425 ftpuser  mem    REG  253,0   2156272    15673 /usr/lib64/libc-2.17.so
bash    1425 ftpuser  mem    REG  253,0     19248    15679 /usr/lib64/libdl-2.17.so
bash    1425 ftpuser  mem    REG  253,0    174576    16034 /usr/lib64/libtinfo.so.5.9
bash    1425 ftpuser  mem    REG  253,0    163312    15666 /usr/lib64/ld-2.17.so
bash    1425 ftpuser  mem    REG  253,0     26970    16003 /usr/lib64/gconv/gconv-modules.cache
bash    1425 ftpuser    0u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425 ftpuser    1u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425 ftpuser    2u   CHR    4,1       0t0     1043 /dev/tty1
bash    1425 ftpuser  255u   CHR    4,1       0t0     1043 /dev/tty1
$ 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按进程列出打开的文件

您还可以使用-c选项后跟进程名称来列出特定进程打开的文件。

 $ sudo lsof -c {process-name}

输出:

 $ sudo lsof -c ssh
COMMAND  PID         USER   FD   TYPE             DEVICE SIZE/OFF     NODE NAME
sshd     997         root  cwd    DIR              253,0      224       64 /
sshd     997         root  rtd    DIR              253,0      224       64 /
sshd     997         root  txt    REG              253,0   852856   425229 /usr/sbin/sshd
sshd     997         root  mem    REG              253,0    61560    15691 /usr/lib64/libnss_files-2.17.so
sshd     997         root  mem    REG              253,0    68192    59651 /usr/lib64/libbz2.so.1.0.6
sshd     997         root  mem    REG              253,0    99944    59680 /usr/lib64/libelf-0.176.so
sshd     997         root  mem    REG              253,0    19896    59686 /usr/lib64/libattr.so.1.1.0
sshd     997         root  mem    REG              253,0    15688    75906 /usr/lib64/libkeyutils.so.1.5
sshd     997         root  mem    REG              253,0    67104   186525 /usr/lib64/libkrb5support.so.0.1 
在 Linux 上使用 lsof 命令的示例
在 Linux 上使用 lsof 命令的示例

按 PID 列出打开的文件

或者,要列出进程打开的文件,但指定其 ID 而不是process-name ,请使用-p标志,后跟process-id

 $ sudo lsof -p {process-id}

输出:

 $ sudo lsof -p 663
COMMAND   PID USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
firewalld 663 root  cwd       DIR              253,0       224       64 /
firewalld 663 root  rtd       DIR              253,0       224       64 /
firewalld 663 root  txt       REG              253,0      7144 50491220 /usr/bin/python2.7
firewalld 663 root  mem       REG              253,0    298828 50617647 /usr/lib64/girepository-1.0/NM-1.0.typelib
firewalld 663 root  mem       REG              253,0    343452 50507562 /usr/lib64/girepository-1.0/Gio-2.0.typelib
firewalld 663 root  mem       REG              253,0     12352 17202092 /usr/lib64/python2.7/lib-dynload/grpmodule.so
firewalld 663 root  mem       REG              253,0     29184 17202105 /usr/lib64/python2.7/lib-dynload/selectmodule.so
firewalld 663 root  mem       REG              253,0    168312   388240 /usr/lib64/libdbus-glib-1.so.2.2.2
firewalld 663 root  mem       REG              253,0     11976 34028597 /usr/lib64/python2.7/site-packages/_dbus_glib_bindings.so
firewalld 663 root  mem       REG              253,0    185712 50507559 /usr/lib64/girepository-1.0/GLib-2.0.typelib
  • 如果要列出所有打开的文件(不包括特定进程打开的文件),请使用-p后跟^process-id
 $ sudo lsof -p ^{process-id}

列出打开的文件,包括目录

要列出已打开特定目录下的文件的进程,请使用+D选项,后跟目录路径。

 $ sudo lsof +D {path}

输出:

 $ sudo lsof +D /var/log
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
auditd     607 root    5w   REG  253,0  1065095   425227 /var/log/audit/audit.log
firewalld  663 root    3w   REG  253,0    13817 17663786 /var/log/firewalld
tuned      999 root    3w   REG  253,0    13395 33574994 /var/log/tuned/tuned.log
rsyslogd  1000 root    6w   REG  253,0     4302 16777753 /var/log/cron
rsyslogd  1000 root    7w   REG  253,0    64740 16777755 /var/log/messages
rsyslogd  1000 root    8w   REG  253,0     5513 16787904 /var/log/secure
rsyslogd  1000 root    9w   REG  253,0      198 16777754 /var/log/maillog
$

如果您不想递归地列出子目录中的文件,请使用-d标志,后跟目录路径。

 $ sudo lsof +d {path}

输出:

 $ sudo lsof +d /var/log
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
firewalld  663 root    3w   REG  253,0    13817 17663786 /var/log/firewalld
rsyslogd  1000 root    6w   REG  253,0     4302 16777753 /var/log/cron
rsyslogd  1000 root    7w   REG  253,0    64740 16777755 /var/log/messages
rsyslogd  1000 root    8w   REG  253,0     5833 16787904 /var/log/secure
rsyslogd  1000 root    9w   REG  253,0      198 16777754 /var/log/maillog
$

重复模式

lsof 可以在重复模式下运行。在重复模式下,lsof 定期生成并打印输出。同样,lsof 使用-r+r标志支持两种重复模式。 -r标志使 lsof 重复执行,直到收到用户的中断/终止信号,而+r标志使 lsof 在输出中没有打开的文件时立即退出重复模式。此外,您可以使用-r+r标志指定延迟时间。

 $ sudo lsof {arguments} -r{time-interval}

输出:

 $ sudo lsof -u ftpuser -c bash +D /usr/lib -a -r3
COMMAND  PID    USER  FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
=======
COMMAND  PID    USER  FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
=======
COMMAND  PID    USER  FD   TYPE DEVICE  SIZE/OFF     NODE NAME
bash    1425 ftpuser mem    REG  253,0 106172832 50548523 /usr/lib/locale/locale-archive
=======

使用网络协议列出打开的文件

lsof 支持列出所有类型的 Linux 文件,包括网络套接字等。因此,您可以使用-i标志列出打开的网络连接的详细信息。

 $ sudo lsof -i

输出:

 $ sudo lsof -i
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd  639       chrony    5u  IPv4  14333      0t0  UDP localhost:323
chronyd  639       chrony    6u  IPv6  14334      0t0  UDP localhost:323
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
master  1229         root   13u  IPv4  18129      0t0  TCP localhost:smtp (LISTEN)
master  1229         root   14u  IPv6  18130      0t0  TCP localhost:smtp (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

要列出特定process-id使用的所有网络连接,您可以使用 lsof,如下所示:

 $ sudo lsof -i -a -p {process-id}

输出:

 $ sudo lsof -i -a -p 997
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    997 root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd    997 root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
$

或者,要列出特定进程使用的所有网络连接,请指定process-name如下所示:

 $ sudo lsof -i -a -c {process-name}

输出:

 $ sudo lsof -i -a -c ssh
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

您可以使用-i标志按网络协议类型(即通过指定协议类型来过滤TCPUDP lsof 的输出。

 $ sudo lsof -i {protocol}

输出:

 $ sudo lsof -i tcp
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
master  1229         root   13u  IPv4  18129      0t0  TCP localhost:smtp (LISTEN)
master  1229         root   14u  IPv6  18130      0t0  TCP localhost:smtp (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

或者

输出:

 $ sudo lsof -i udp
COMMAND PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd 639 chrony    5u  IPv4  14333      0t0  UDP localhost:323
chronyd 639 chrony    6u  IPv6  14334      0t0  UDP localhost:323
$

按端口列出打开的文件

您还可以使用-i标志使用以下命令语法按port number过滤 lsof 的输出。

 $ sudo lsof -i :{port-number}

输出:

 $ sudo lsof -i :22
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
sshd     997         root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

按 IPv4/IPv6 列出打开的文件

有一个选项可以将网络连接列表限制和过滤为 IPv4 或 IPv6。要仅获取 IPv4 列表,请使用以下命令语法:

 $ sudo lsof -i4

输出:

 $ sudo lsof -i4
COMMAND  PID         USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd  639       chrony    5u  IPv4  14333      0t0  UDP localhost:323
sshd     997         root    3u  IPv4  17330      0t0  TCP *:ssh (LISTEN)
master  1229         root   13u  IPv4  18129      0t0  TCP localhost:smtp (LISTEN)
sshd    1235         root    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
sshd    1239 abhisheknair    3u  IPv4  18318      0t0  TCP centos7vm:ssh->192.168.1.61:23566 (ESTABLISHED)
$

或者要仅获取 IPv6 详细信息,请使用:

 $ sudo lsof -i6

输出:

 $ sudo lsof -i6
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd  639 chrony    6u  IPv6  14334      0t0  UDP localhost:323
sshd     997   root    4u  IPv6  17339      0t0  TCP *:ssh (LISTEN)
master  1229   root   14u  IPv6  18130      0t0  TCP localhost:smtp (LISTEN)
$

列出 NFS 上打开的文件

lsof 还可以列出用户当前打开的所有 NFS 文件。

 $ sudo lsof -N -u abhisheknair -a

列出锁定和删除的文件

即使文件已在 Linux 上删除,它也可能仍被一个或多个进程锁定。因此,这些文件不会出现在使用ls命令等的常规文件系统列表中,但它们仍然消耗磁盘空间,如df输出中报告的那样。这种情况尤其发生在故意删除大文件以清理磁盘空间而不释放进程锁的情况下。您可以使用 lsof 找到此类进程,如下所示:

 $ sudo lsof {path} | grep deleted

输出:

 $ sudo lsof / | grep deleted
firewalld  654         root    8u   REG  253,0      4096 16777726 /tmp/#16777726 (deleted)
tuned      968         root    8u   REG  253,0      4096 16777720 /tmp/#16777720 (deleted)
$

结论

lsof 提供了各种选项来根据您的需要自定义输出。对于日常系统和网络管理任务来说,这是一个有用的实用程序。您可以组合不同的参数,这使其更加有用,并且更容易获得您想要的输出。有关所有支持的参数及其用法,请参阅 lsof 手册页。

 $ man lsof