try.directtry.direct
Article preview image

The power of lsof

Linux has some mighty commands which can come in handy to system administrators or power users, and lsof is one of them. This command stands for ‘List of Open Files.’ In Linux, everything is a file, including network connection, devices, directories, network sockets, etc. Here, lsof helps you identify which files are being used by which processes. You can also track user activity by checking files and processes used by that specific user using the lsof command. Moreover, thanks to lsof you can quickly find additional information such as the port used by services/files, sockets in use, etc. Hence, you can say that the lsof command is capable of replacing commands like netstat and PS.

This guide will provide you with a basic understanding of lsof command with practical examples.


1. List of All Open Files


By running just the 'lsof' command, you will get a list of all system's open files.


root@beta:~# lsof
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 252,1 4096 2 /
systemd 1 root rtd DIR 252,1 4096 2 /
systemd 1 root txt REG 252,1 1616248 42953 /lib/systemd/systemd
systemd 1 root mem REG 252,1 1700792 31573 /lib/x86_64-linux-gnu/libm-2.27.so
----

Note: Here, the output of the lsof command is very long. Hence, the output for most of the commands in this post has been truncated. The ellipsis (…) at the end will show the outputs that have been omitted.

The lsof command output is very long and extensive and can be difficult to handle. Therefore, it is better to combine it with the less command in the following way:


lsof | less

Here, let's understand the following columns from the lsof command output:

COMMAND - the command associated with the process that opened the file

PID - process ID which belongs to the process that opened the file

TID - Task Identification number. If it is blank, it indicates that it is a process and not a task.

USER - User or Owner

FD - shows the file descriptor of the file

TYPE - type of node associated with the file

DEVICE - contains the device numbers with commas

SIZE - file size in bytes

NODE - node number

NAME - full path of the file name


2. List of All Files by Filenames


Run the below-given command to list all the processes that have opened a specific file:


root@beta:~# lsof /var/log/nginx/access.log
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1009 root 14w REG 252,1 53471 1052574 /var/log/nginx/access.log
nginx 20013 www-data 14w REG 252,1 53471 1052574 /var/log/nginx/access.log

3. View All Open Files from a Directory


Another benefit of the lsof command is that it allows you to check the open files from a specific directory. To do this, just add the +D option followed by the directory you want to analyze.


root@beta:~# lsof +D /var/log/nginx/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1009 root 2w REG 252,1 0 1054320 /var/log/nginx/error.log
nginx 1009 root 4w REG 252,1 0 1054324 /var/log/nginx/access.log
---

The above command will be helpful when you aren’t able to unmount a directory or when the system shows a “Device or Resource Busy” error.


4. List of Files Opened by a Process


You can also check the files opened by a specific system process using the -c option. For example:


root@beta:~# lsof -c node
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node\x20/ 4066 root cwd DIR 252,1 4096 783350 /var/www/html/demo_server
node\x20/ 4066 root rtd DIR 252,1 4096 2 /
node\x20/ 4066 root txt REG 252,1 41226208 14617 /usr/bin/node
---

5. List only the PID of the specific process


You can easily find out all the PIDs associated with a specific process. By executing the below command, you can list the PIDs of the node process. The -t option will give you the list of PIDs.


root@beta:~# lsof -t -i -c node
748
1009
---

6. Search Open Files by PID


The lsof command allows you to list files based on their PIDs. The below-given command shows all files associated with the process ID 4066.


lsof -p 4066

Output:

COMMAND PID USER   FD   TYPE          DEVICE SIZE/OFF NODE NAME
node\x20/ 4066 root cwd DIR 252,1 4096 783350 /var/www/html/demo_server
node\x20/ 4066 root rtd DIR 252,1 4096 2 /
---

7. List of All Files Opened by a Specific User


You can list all the files opened by a specific user as shown in the following command:


lsof -u user1

Output:


COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
bash 18348 user1 cwd DIR 8,1 57 537314138 /home/user1
bash 18348 user1 rtd DIR 8,1 325 128 /
bash 18348 user1 txt REG 8,1 1183448 1074696841 /usr/bin/bash
------

Similarly, you can give multiple usernames as follows:


lsof -u user1,user2,user3

You can also find out what files and commands were checked and who was looking at them by executing commands like below:


lsof -i -u user1 | grep cwd

Output:


bash   19075        user1  cwd DIR 8,1    78  537314138 /home/user1
ping 19127 user1 cwd DIR 8,1 78 537314138 /home/user1
bash 19154 user1 cwd DIR 8,1 78 537314138 /home/user1
vim 19181 user1 cwd DIR 8,1 78 537314138 /home/user1

You will notice that user1 is using the ping command and vim editor that he opened.


8. List All the Open Files Except a Specific User


You can also exclude a list of files open by a specific user by running the below command:


lsof -u ^root

The above command lists all the open files on the system except the root user.


9. Kill All Processes of a Specific User


In some cases, you might need to kill all the processes opened by a specific user. The below command can be used to kill all the processes of the developer1 user.


kill -9 `lsof -t -u developer1`

10. Network Information


The lsof command has much more power than you think, as it can work as a netstat command replacement. You can use lsof with -i to see all the connections.

Run the below-given command to check all network connections of your system.


root@beta:~# lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd-r 748 systemd-resolve 12u IPv4 15733 0t0 UDP localhost:domain
systemd-r 748 systemd-resolve 13u IPv4 15734 0t0 TCP localhost:domain (LISTEN)
sshd 989 root 3u IPv4 18300 0t0 TCP *:ssh (LISTEN)
sshd 989 root 4u IPv6 18319 0t0 TCP *:ssh (LISTEN)
nginx 1009 root 16u IPv6 18334 0t0 TCP *:https (LISTEN)

You can filter it using -i 4 or -i 6 to list either IPv4 or IPv6 files.

For IPV4


lsof -i 4

For IPV6


lsof -i 6

11. List All TCP or UDP Files


Next, by executing the below command, you will be able to list all the TCP processes:


root@beta:~# lsof -i TCP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd-r 748 systemd-resolve 13u IPv4 15734 0t0 TCP localhost:domain (LISTEN)
sshd 989 root 3u IPv4 18300 0t0 TCP *:ssh (LISTEN)
nginx 1009 root 16u IPv6 18334 0t0 TCP *:https (LISTEN)
-----

You can use the following command to list all UDP processes through lsof:


root@beta:~# lsof -i UDP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd-r 748 systemd-resolve 12u IPv4 15733 0t0 UDP localhost:domain

12. List All Processes Listening to TCP ports


Use the lsof command as shown in the below-given example to find all the processes listening to the TCP port:


root@beta:~# sudo lsof -i -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd-r 748 systemd-resolve 13u IPv4 15734 0t0 TCP localhost:domain (LISTEN)
nginx 1009 root 16u IPv6 18334 0t0 TCP *:https (LISTEN)
nginx 1009 root 17u IPv4 18335 0t0 TCP *:https (LISTEN)
----

13. List of Established Connections


To find the currently established connections, simply run the below command:


lsof -i -sTCP:ESTABLISHED

Output:


COMMAND PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd 27785 root 3u IPv4 9951161 0t0 TCP beta:ssh->192.168.1.21:5653 (ESTABLISHED)
----

14. Searching for Active Connections from a Specific Source


Occasionally, you will want to find out all the active connections from your server's specific IP address/source. To do this, use the below-given command:


lsof -i @192.168.1.74COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ssh 13997 soham 5u IPv4 268962 0t0 TCP rockylinux-8:45598->192.168.1.74:ssh (ESTABLISHED)
ssh 15608 soham 4u IPv4 333266 0t0 TCP rockylinux-8:46366->192.168.1.74:ssh (ESTABLISHED)

15. Looking for the Process Listening Specific Port


Execute the below command to list any process listening to the port 8081:


lsof -i:8081

Additionally, you can kill any process listening to the port 8081 by running the following command:


kill -9 $(lsof -t -i:8081)

You can also specify protocol as shown in the following command:


root@beta:~# lsof -i TCP:443
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1009 root 16u IPv6 18334 0t0 TCP *:https (LISTEN)
nginx 1009 root 17u IPv4 18335 0t0 TCP *:https (LISTEN)
---

16. List of Open Connections with a Port Range


Next, list all the running processes of open files from port 3000-4000:


root@beta:~# lsof -i TCP:3000-4000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
PM2\x20v5 24403 root 22u IPv6 9735497 0t0 TCP *:3001 (LISTEN)
PM2\x20v5 24403 root 24u IPv6 9709625 0t0 TCP *:3000 (LISTEN)
PM2\x20v5 24403 root 25u IPv6 5114098 0t0 TCP *:3002 (LISTEN)

17. Disable Port Conversion


Using -P option, you can disable port number conversion, which saves a considerable amount of time when there are too many files of this kind.


lsof -i -Tqs -P

For better understanding, use the 'time' command with -P option to compare the execution time.


time lsof -i -Tqs

Output:


COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ssh 5684 root 3u IPv4 55557 0t0 TCP beta:36600->192.168.1.52:ssh (ESTABLISHED QR=0 QS=36)

real 0m4.855s
user 0m0.012s
sys 0m0.021s

time lsof -i -Tqs -P

Output:


COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ssh 5684 root 3u IPv4 55557 0t0 TCP beta:36600->192.168.1.52:ssh (ESTABLISHED QR=0 QS=36)

real 0m2.003s
user 0m0.012s
sys 0m0.007s

18. Disable Host Conversion


You can also disable hostname conversion to improve the performance and save time. Just like with the port name conversion.


time lsof -i -n | head -3

Output:


COMMAND  PID         USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
systemd-r 748 systemd-resolve 12u IPv4 15733 0t0 UDP 127.0.0.53:domain
systemd-r 748 systemd-resolve 13u IPv4 15734 0t0 TCP 127.0.0.53:domain (LISTEN)

real 0m0.051s
user 0m0.009s
sys 0m0.025s

19. List of Deleted Files


You will often notice that the df and the du command show different disk usage of the same file system. In this case, the Isof command comes handy, as it allows us to find files that were removed from the system. Furthermore, it will enable one to check which files were opened by which processes. Hence, it gives a clear idea of the activities happening.


lsof / | grep -i "deleted"

Output:


root@beta:~# lsof / | grep -i "deleted"
networkd- 927 root txt REG 252,1 4526456 1841 /usr/bin/python3.6 (deleted)
unattende 983 root txt REG 252,1 4526456 1841 /usr/bin/python3.6 (deleted)
---

20. Help and Manual Pages


The lsof command comes with many options and switches. You can check lsof quick help and manual pages to learn the lsof command more deeply.


lsof --help

man lsof

Now you know the fundamentals of the lsof command: how it comes to aid in the usual tasks like debugging, troubleshooting, finding deleted files, etc., and how it gives a clear idea regarding the whereabouts of the files.