lsof is a powerful utility available for Linux and Unix-based systems which literally stands for ‘list (of) open files’.

Its main function is to retrieve details about various types of files opened up by different running processes. These files can be regular files, directories, block files, network sockets, named pipes, etc.

With lsof, you can find different processes locking up a file or directory, a process listening on a port, a user’s process list, what all files a process is locking. We’ll first cover its installation and then some common usage examples in this article.

Installing lsof

lsof isn’t available by default on most Linux distributions but can be easily installed. Use the below command to install lsof:

CentOS / RHEL / Fedora:

$ sudo yum install lsof

for CentOS/RHEL 8, you can use the DNF command

$ sudo dnf install lsof

Ubuntu / Debian:

$ sudo apt install lsof

Getting Help

You can get a summarised list of lsof supported options using -? or -h flag.

$ 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]] repeat every t seconds (15);    until no files, - forever.
       An optional suffix to t is m; m must separate t from  and
       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.
$

To check detailed installed version information, use:

$ 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: [email protected]
    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.
$

Output Fields

lsof output field structure by default is like:

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

Most of these fields are self-explanatory except for  FD and TYPE fields that are somewhat unique to lsof and will be explored briefly.

FD refers to the File Descriptor number of the file and TYPE refers to the type of the node associated with the file. We’ll now review the supported values for both these fields.

FD field can contain the following values:

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 field is followed by one or more characters describing the mode under which the file is open:

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.

Mode character for FD then further can be followed by LOCK character whose description is given below:

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.

Similarly, TYPE field can contain GDIR, GREG, VDIR, VREG, IPV4, IPV6 etc. To get a complete list of supported TYPE in lsof, refer its man page.

Common Usage

Below are some of the popular usage of the lsof command. The command works across Linux variants and all command-line arguments listed below examples should work across all platforms, considering the same lsof version.

List all open files

Running lsof without any options will list all files that are currently open by active processes.

$ sudo lsof | less

Output:

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

List by filename

To list all processes that have opened a specific file, we can specify file-name as an argument:

$ sudo lsof {file-name}

Output:

$ 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
$

List open files by username

In a multi-user system, you can filter the list of files by specific user-owned processes, using -u flag followed by username.

$ sudo lsof -u {username}

Output:

$ 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

Alternatively, if you want to list files that are opened by any user except a specific one, use -u flag followed by ^username as shown below:

$ sudo lsof -u ^{username}

Output:

$ 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

One way you can use lsof is for situations where you want to kill all processes by a specific user quickly in a single command. We can combine kill with lsof as shown in the below example to achieve this (execute as root):

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

As seen in the above example, we can use -t flag to filter out all other information except process-id. This can be useful in automation and scripting as shown in the previous example by combining it with kill command.

$ sudo lsof -t -u {username}

Output:

$ sudo lsof -t -u abhisheknair
1239
1240
$

With lsof, we can combine multiple arguments using OR logic as shown below:

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

Output:

$ 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
$

Alternatively, if you want to use AND logic condition use -a flag.

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

Output:

$ 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
$

List open files by process

We can also list files opened by a particular process by using -c option followed by the process name.

$ sudo lsof -c {process-name}

Output:

$ 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

List open files by PID

Alternatively, to list files opened by a process but instead of process-name you want to specify its ID, you can use -p flag followed by process-id.

$ sudo lsof -p {process-id}

Output:

$ 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
  • If you want to list every open file except for the ones opened by a particular process, use -p followed by ^process-id.
$ sudo lsof -p ^{process-id}

List open files containing directory

To list processes that opened files under a specific directory, use D option followed by directory path.

$ sudo lsof  D {path}

Output:

$ 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
$

If you don’t want to recursively list files inside sub-directories, use -d flag followed by directory path.

$ sudo lsof  d {path}

Output:

$ 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
$

Repeat mode

lsof can be run in repeat mode. In repeat mode, lsof will generate and print output at regular intervals. Again, there are two repeat modes supported by lsof, i.e., with -r and r flags. With -r flag, lsof repeats to execute until it receives an interrupt/kill signal from the user while with r flag, lsof repeat mode will end as soon as its output has no open files. Additionally, we can specify time delay with -r or r flag.

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

Output:

$ 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
=======

List open files with network protocol

lsof supports the listing of any type of Linux files which includes network sockets etc. As such we can list details of open network connections using -i flag.

$ sudo lsof -i

Output:

$ 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)
$

To list all network connections in use by a specific process-id, you can use lsof as:

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

Output:

$ 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)
$

Or to list all network connections in use by a specific process, we can give process-name as:

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

Output:

$ 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)
$

We can filter the output of lsof with -i flag by network protocol type, i.e., TCP or UDP by specifying the protocol type.

$ sudo lsof -i {protocol}

Output:

$ 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)
$

OR

Output:

$ 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
$

List open files by port

We can also filter the output of lsof with -i flag by port number using command syntax as below:

$ sudo lsof -i :{port-number}

Output:

$ 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)
$

List open files by IPv4/IPv6

There’s an option to filter network connections listing by limiting it to either IPv4 or IPv6. Use below command syntax to get only IP v4 listing:

$ sudo lsof -i4

Output:

$ 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)
$

OR to get only IPv6 details, use:

$ sudo lsof -i6

Output:

$ 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)
$

List open files on NFS

lsof can also list all NFS files currently open by a user.

$ sudo lsof -N -u abhisheknair -a

List locked deleted files

Sometimes it happens that files are deleted in Linux but still are being locked by one or more processes. As such, those files don’t list on normal file system listing using ls command etc. but they still consume disk space as reported by df output, this happens especially for large files deleted on purpose to clear disk space without releasing the process lock. You can find such processes using lsof as:

$ sudo lsof {path} | grep deleted

Output:

$ 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)
$

Conclusion

lsof offers a range of options to customize its output according to your needs. It’s a useful utility in day-to-day system and network administration tasks. The ability to combine different arguments together makes it all the more useful and allows you to get the required output easily. Refer lsof man page to learn all supported arguments and their usage.

$ man lsof