Lsof stands fo list open files and it's a command to be used when you want to investigate "resources" used by a process hence to gain some insight about what that process is actually doing behind the scenes. Through these resources you can also find internet related files such as sockets but I do not recommend to use lsof for this because:
ss command is dedicated for this and it is a lot faster
when lsof is used it may trigger system logs or even notify in some way the admin of that system
Lsof has many options and I will list the ones which I consider useful but before first I will discuss the columns displayed for a process using -p option. I am using zsh and I have multiple shells running, we will check lsof for one of the zsh processes.
╰─ pgrep zsh
1836
1855
2111
2112
2128
2131
2167
2168
14334
14345
14379
14380
I will pick the first one and use lsof -p ${PID}
╰─ lsof -p 1836
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zsh 1836 tony cwd DIR 254,0 4096 10747906 /home/tony
zsh 1836 tony rtd DIR 254,0 4096 2 /
zsh 1836 tony txt REG 254,0 975848 13386404 /usr/bin/zsh
zsh 1836 tony mem REG 254,0 23440 14422275 /usr/lib/zsh/5.9/zsh/files.so
zsh 1836 tony mem REG 254,0 14160 14422281 /usr/lib/zsh/5.9/zsh/net/socket.so
zsh 1836 tony mem REG 254,0 14224 14422772 /usr/lib/zsh/5.9/zsh/termcap.so
zsh 1836 tony mem REG 254,0 21200 14422278 /usr/lib/zsh/5.9/zsh/mathfunc.so
zsh 1836 tony mem REG 254,0 159328 14422268 /usr/lib/zsh/5.9/zsh/complete.so
zsh 1836 tony mem REG 254,0 335392 14422776 /usr/lib/zsh/5.9/zsh/zle.so
zsh 1836 tony mem REG 254,0 48800 14422765 /usr/lib/zsh/5.9/zsh/parameter.so
zsh 1836 tony mem REG 254,0 67568 14422269 /usr/lib/zsh/5.9/zsh/complist.so
zsh 1836 tony mem REG 254,0 18528 14422272 /usr/lib/zsh/5.9/zsh/datetime.so
zsh 1836 tony mem REG 254,0 22536 14422770 /usr/lib/zsh/5.9/zsh/stat.so
zsh 1836 tony mem REG 254,0 14304 14422777 /usr/lib/zsh/5.9/zsh/zleparameter.so
zsh 1836 tony mem REG 254,0 14160 14422767 /usr/lib/zsh/5.9/zsh/regex.so
zsh 1836 tony mem REG 254,0 14160 14422780 /usr/lib/zsh/5.9/zsh/zselect.so
zsh 1836 tony DEL REG 254,0 13388621 /usr/lib/locale/locale-archive
zsh 1836 tony DEL REG 254,0 13379232 /usr/lib/libc.so.6
zsh 1836 tony DEL REG 254,0 13379249 /usr/lib/libm.so.6
zsh 1836 tony mem REG 254,0 470232 13374435 /usr/lib/libncursesw.so.6.3
zsh 1836 tony DEL REG 254,0 13374990 /usr/lib/libcap.so.2.65
zsh 1836 tony mem REG 254,0 34832 14422781 /usr/lib/zsh/5.9/zsh/zutil.so
zsh 1836 tony mem REG 254,0 32208 14422771 /usr/lib/zsh/5.9/zsh/system.so
zsh 1836 tony mem REG 254,0 14224 14422773 /usr/lib/zsh/5.9/zsh/terminfo.so
zsh 1836 tony mem REG 254,0 14832 14422276 /usr/lib/zsh/5.9/zsh/langinfo.so
zsh 1836 tony DEL REG 254,0 13379220 /usr/lib/ld-linux-x86-64.so.2
zsh 1836 tony 0u CHR 136,1 0t0 4 /dev/pts/1
zsh 1836 tony 1u CHR 136,1 0t0 4 /dev/pts/1
zsh 1836 tony 2u CHR 136,1 0t0 4 /dev/pts/1
zsh 1836 tony 10u CHR 136,1 0t0 4 /dev/pts/1
zsh 1836 tony 11w FIFO 0,36 0t0 146 /tmp/gitstatus.POWERLEVEL9K.1000.1836.1665816502.1.fifo (deleted)
zsh 1836 tony 12w FIFO 0,36 0t0 149 /tmp/p10k.worker.1000.1836.1665816496.fifo (deleted)
zsh 1836 tony 16r FIFO 0,13 0t0 34535 pipe
zsh 1836 tony 17r FIFO 0,13 0t0 33250 pipe
Columns COMMAND, PID and USER describe themselves so I will jump to FD column, which stands for open file type. The most popular open file type is a file descriptor (FD) which is sometimes confused with open file. All file descriptors are open files but not all open files are files descriptors!!! I recommend checking file descriptors tutorial.
The last 8 lines of lsof output are files descriptors, they are always represented through a positive integer. Other types of FDs:
mem - Memory mapped file, usually for share library
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
DEL - a file which was deleted/changed after it has been opened
pd - parent directory
rtd - root directory
tr - kernel trace file (OpenBSD)
txt - program text (code and data)
v86 - VP/ix mapped file
Column TYPE refers to the actual type of file like REG & DIR which have a path on disk, CHR and FIFO which do not have. I mentioned about FD column that it stands also for the type of file but from functionality point of view, like what is the purpose of that file when it comes to the process which opened it. This actual type can be seen easily in the first column from output of ls -l command.
╰─ ls -l
-rw-r--r-- 1 tony tony 2372 mai 14 12:52 install_notes.txt
drwxr-xr-x 2 tony tony 4096 mar 22 2022 Troubleshoot_Pacman_Mirrors_files
-rw-r--r-- 1 tony tony 591916 mar 22 2022 Troubleshoot_Pacman_Mirrors.html
REG - regular file, file that show up in directory - represented by "-" in first column of ls -l output
DIR - directory - represented by "d" in first column of ls -l output
╭─░▒▓ /dev/pts
╰─ ls -l
crw--w---- 1 tony tty 136, 0 oct 15 09:44 0
crw--w---- 1 tony tty 136, 1 oct 15 11:17 1
crw--w---- 1 tony tty 136, 2 oct 15 11:44 2
c--------- 1 root root 5, 2 oct 15 09:41 ptmx
CHR - character file (file living only in memory of OS) - represented by "c" in first column of ls -l output
╰─ ls -l
total 0
prw-r--r-- 1 tony tony 0 oct 15 11:47 socket-input
FIFO - first-in-first-out (named pipes) - represented by "p" in first column of ls -l output. You will find more details about pipes, how to create them and use them in pipes
I need to mention also that you can see two other letters in the first column of ls -l output and those are:
- "l" for links (hard/soft)
- "b" for devices which represent NVM memory(storage) - ex: device on which "/" is mounted on
Column DEVICE format differs depending on type of open file as follows:
1) For REG, DIR, CHR and FIFO the device numbers separated by "," will be displayed. I do not know how kernel allocates these numbers but you can use this to find out the file system on which open files are located. We can see the majority have 254, 0 and if we navigate to /dev where all devices are present and ls -lR | grep 254, we will see that the first device is dm-0, which in my case it represents the filesystem mounted on root "/"
╭─░▒▓ /dev
╰─ ls -lR | grep 254
brw-rw---- 1 root disk 254, 0 oct 15 09:41 dm-0
crw------- 1 root root 254, 0 oct 15 09:41 gpiochip0
╰─ df
Filesystem 1K-blocks Used Available Use% Mounted on
dev 3997580 0 3997580 0% /dev
run 4010416 1760 4008656 1% /run
/dev/dm-0 244709816 143003980 89202432 62% /
So we know that all open files with "254, 0" on DEVICE column have a path on filesystem dm-0 which is mounted on "/". Some of the open files have 136,0 as device numbers and in this case the name which is the actual path of the character file indicates the same file which we will find using device numbers.
╰─ ls -lR | grep 136
crw--w---- 1 tony tty 136, 0 oct 16 10:18 0
crw--w---- 1 tony tty 136, 1 oct 16 2022 1
We see character file "1" which is in /dev/pts (device/pseudoterminals) and we can see it's whole path also in the output of lsof
zsh 1836 tony 0u CHR 136,1 0t0 4 /dev/pts/1
zsh 1836 tony 1u CHR 136,1 0t0 4 /dev/pts/1
zsh 1836 tony 2u CHR 136,1 0t0 4 /dev/pts/1
zsh 1836 tony 10u CHR 136,1 0t0 4 /dev/pts/1
2) For open files which have "unix" in the FD column we will see a memory address (8 bytes long). I do not know if the first 4 bytes are displayed as 0x00 because they should remain hidden but in man of lsof it says the following: DEVICE column contains:
the address of the private data area of a Solaris socket stream
or a kernel reference address that identifies the file (The kernel reference address may be used for FIFO's, for example.)
or the base address or device name of a Linux AX.25 socket device
Usually only the lower thirty two bits of Tru64 UNIX kernel addresses are displayed
As an example, I've ran lsof for firefox (process_ID = 1440) and I've grep-ed output for unix to filter all files with column FD = unix and I've displayed the first 3 lines of output:
╰─ lsof -p 1440 | grep unix
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
firefox 1440 tony 1u unix 0x00000000f5421af8 0t0 25469 type=STREAM (CONNECTED)
firefox 1440 tony 2u unix 0x00000000f5421af8 0t0 25469 type=STREAM (CONNECTED)
firefox 1440 tony 4u unix 0x00000000e999ecc8 0t0 31434 type=STREAM (CONNECTED)
...
That's about it for DEVICE column, as for SIZE/OFFSET column there's not much to know, as stated in lsof manual "is the size of the file or the file offset in bytes. A value is displayed in this column only if it is available". The NODE column refers to the kernel inode ID. This kernel inode table contains all open files in the OS and each open file is associated with an unique NODE ID. Open files which have an actual path on disk and don't live only in RAM can be found by this node id with the find command:
find {path_on_which_file_system_is_mounted_on} -inum {NODE_ID} -print
For more details about i-node please check file descriptors.