As you might already know many interesting Linux resources are modeled as files. File define a simple and well understood interface for linux tools. In this article an would like to highlight a very useful Linux tool utilizes exactly this, a lsof (aka “list open files”) command.

To describe lsof in one sentence. Actually it shows all files used by some processes of a system, but it’s more interesting as it might sound. Let’s get best of it!

In the absence of any options, lsof lists all open files belonging to all active processes of a system. Try it:

lsof

now let’s go to more interesting cases.

Network connections with lsof

The interesting option here is the -i that should be followed by the Internet address which is specified in the following form:

[4|6][protocol][@hostname|hostaddr][:service|port]

4 and 6 stand for ip protocol versions, the rest should be self expanded. Let’s get hands on:

#Show all open connections
lsof -i

# Show all open TCP connections
lsof -i TCP 

Looking for specific ports…

#Examples of: Show TCP connection on 636, 80 and UDP port range 3000-3025
lsof -i TCP:636
lsof -i TCP:80
lsof -i UDP:3000-3025

#every protocol on port 22
lsof -i :22

to show all listening objects use:

lsof -i| grep LISTEN
#or with options -P and -a
lsof -i -P -a| grep LISTEN
  • -P forces lsof to show port numbers instead of protocol name (22 vs ssh, 5671 vs amqps)
  • -a forces to show ip addresses and not to resolve DNS names

More examples

Show LDAP incoming connections:

lsof -i TCP@192.168.0.1:636 ()
#java  890 root  18u  IPv6 8332031
#TCP myserver.com:42936 myserver.com:ldaps (ESTABLISHED)

Who uses SMTP?

lsof -i :25
#COMMAND  PID USER   FD   TYPE        DEVICE SIZE/OFF NODE NAME
#sendmail 401 root    5u  IPv4 0x300023cc141      0t0  TCP *:smtp (LISTEN)
#sendmail 401 root    6u  IPv6 0x3000243c200      0t0  TCP *:smtp (LISTEN)

The command option

-c option allows seeing what files are open by a particular command.

lsof -c mysq
lsof -c ruby

Find files that are open by a particular device or a file

lsof /dev/cdrom
lsof /tmp/obscure.lock

Find files that are opened by a user guest

lsof –u guest
#vi   5200 guest txt REG 3,1   242601 245773 /bin/vi

Recursive watch

And at last, use -r option for monitoring. Here is an example of periodically (every 10 seconds) refresh of connection status for a concrete application started as php.

lsof -r 10 -c php -a -i :1521

It gives periodically all 1521 port connections. 1521 is a typical Oracle DB connection port, so that example may serve you as a base for a script that monitors the connection growth of your PHP applications.

lsof & PID

Next one uses the -t parameter which causes lsof return only a process id of a file using the application. So the following command allows you to kill all applications that are using the provided file.

kill -9 `lsof -t /tmp/obscure.lock`

Coming from other side, having a PID, we can list all resources used by the process, which might be very useful as well.

lsof -p 8698

#COMMAND    PID USER   FD      TYPE DEVICE SIZE/OFF       NODE NAME
#docker-pr 8698 root  cwd       DIR  253,1     4096        128 /
#docker-pr 8698 root  rtd       DIR  253,1     4096        128 /
#docker-pr 8698 root  txt       REG  253,1  1593264   17005705 /usr/bin/docker-proxy
#docker-pr 8698 root  mem       REG  253,1  2127336   33647913 /usr/lib64/libc-2.17.so
#docker-pr 8698 root  mem       REG  253,1   144792   33647939 /usr/lib64/libpthread-2.17.so
#docker-pr 8698 root  mem       REG  253,1   164112   33647906 /usr/lib64/ld-2.17.so
#docker-pr 8698 root    0r      CHR    1,3      0t0       4558 /dev/null
#docker-pr 8698 root    1w      CHR    1,3      0t0       4558 /dev/null
#docker-pr 8698 root    2w      CHR    1,3      0t0       4558 /dev/null
#docker-pr 8698 root    4u     IPv6  97112      0t0        TCP *:25672 (LISTEN)
#docker-pr 8698 root    5u  a_inode    0,9        0       4554 [eventpoll]
#docker-pr 8698 root   10r      REG    0,3        0 4026531956 net