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:
Output
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.
Output
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:
Output
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.
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:
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:
You can also find out what files and commands were checked and who was looking at them by executing commands like below:
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:
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.
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.
Output
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
For IPV6
11. List All TCP or UDP Files
Next, by executing the below command, you will be able to list all the TCP processes:
Output
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:
Output
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:
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.74
bash
Output
COMMAND 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.
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.
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.