Linux

lsof: The Complete Guide to Finding Open Files

The lsof (list open files) command is an essential tool for system administrators and developers to diagnose file, port, and process issues. This guide shows how to use lsof effectively for real-world tasks.

Updated at February 16, 2026
15-20 minutes
Medium
FixPedia Team
Применимо к:Ubuntu 20.04+CentOS 7+Debian 10+RHEL 8+Any distribution with lsof package installed

Introduction / Why This Is Needed

lsof (List Open Files) is a powerful command-line utility in Linux that allows you to see which processes in the system have open files, directories, network sockets, devices, etc. In Unix-like systems, almost everything is a file, so this command is a primary diagnostic tool for system administrators, developers, and DevOps engineers.

You will learn to solve common problems:

  • "Port 8080 is already in use, but which process is using it?"
  • "I can't delete the file /tmp/app.log; it says it's in use. Who is holding it?"
  • "What network connections is my application actively using?"
  • "Why is a process consuming so many file descriptors?"

This guide contains specific, tested commands with explanations that you can use immediately.

Requirements / Preparation

  1. Access to a Linux terminal (Ubuntu, CentOS, Debian, RHEL, Fedora, etc.).
  2. Superuser (sudo) privileges. Many commands, especially those related to network ports and processes of other users, require administrator rights to display information correctly.
  3. An installed lsof package. It is included by default in most distributions, but it might be missing in minimal installations.
    • Debian/Ubuntu: sudo apt update && sudo apt install lsof
    • RHEL/CentOS/Fedora: sudo yum install lsof or sudo dnf install lsof
  4. Basic understanding of the command line and the PID (process identifier) concept.

Step-by-Step Guide

Step 1: Basic Syntax and Viewing All Open Files

Running lsof without arguments will list all open files for the current user.

lsof

Example output (simplified):

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    1234 user  cwd    DIR    8,1     4096    2 /
bash    1234 user  txt    REG    8,1  1028096 12345 /bin/bash
bash    1234 user  mem    REG    8,1  1985224 67890 /lib/x86_64-linux-gnu/libc-2.31.so
...

Key columns:

  • COMMAND — the name of the process's executable file.
  • PID — the process identifier.
  • USER — the owner of the process.
  • FD — the file descriptor (cwd — current directory, txt — executable code, mem — memory-mapped region).
  • TYPE — the file type (REG — regular file, DIR — directory, CHR — character device, IPv4/IPv6 — network socket).
  • NAME — the path to the file or socket information.

For a complete system-wide view (all users), use sudo:

sudo lsof

Step 2: Finding Processes That Opened a Specific File or Directory

This is the most common task: "Who is using this file?"

For a single file:

lsof /path/to/file.log

Example: lsof /var/log/syslog

Recursive search in a directory (all files inside):

lsof +D /home/user/documents/

⚠️ Important: The +D option can work very slowly on large directories, as it checks every subdirectory. For a quick check of a specific file, use the first method.

Step 3: Finding a Process by Its PID (What a Process Has Opened)

If you know a process's PID (e.g., 5678), see what resources it uses:

lsof -p 5678

You can specify multiple PIDs separated by commas: lsof -p 5678,9012.

This is useful for analyzing a running daemon, container, or suspicious process.

Step 4: Finding the Process Listening on a Network Port

The classic task: "Port 3000 is in use, which process is listening on it?"

sudo lsof -i :3000

Example output:

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    4321 user   20u  IPv6 123456      0t0  TCP *:3000 (LISTEN)

Here you can see that port 3000 is being listened to by the node (Node.js) process with PID 4321.

Search by service name/port (if the port is known, e.g., 80 for HTTP):

sudo lsof -i :http
# or
sudo lsof -i :80

Step 5: Advanced Filtering of Network Connections

The -i option combinations allow for fine-tuning filters.

TCP connections only:

sudo lsof -i tcp

UDP sockets only:

sudo lsof -i udp

Connections in LISTEN state (listening ports):

sudo lsof -i -s tcp:listen

The -s option allows filtering by connection state (established, listen, close_wait, etc.).

Connections from or to a specific IP address:

# All connections from remote address 192.168.1.100
sudo lsof -i @192.168.1.100

# All connections on local interface 192.168.1.5:80
sudo lsof -i @192.168.1.5:80

Step 6: Finding Files Opened by a Specific User

To see all files opened by the apache or www-data user:

sudo lsof -u apache

You can specify multiple users: lsof -u user1,user2.

Step 7: Combining Filters (Logical AND)

Filters in lsof are combined using AND (logical multiplication) by default. This is very powerful.

Example: Find all TCP connections (-i tcp) that are listening (-s tcp:listen) and belong to a process named nginx (-c nginx).

sudo lsof -i tcp -s tcp:listen -c nginx

Where:

  • -c <command> — filters by the first characters of the command name (you can use ^nginx for an exact match from the start of the string).

Another example: What files does the postgres user open in the /var/lib/postgresql directory?

sudo lsof -u postgres +D /var/lib/postgresql

Step 8: Useful Options for Convenient Output

  • -n — do not convert IP addresses to hostnames (speeds up output).
  • -P — do not convert port numbers to service names (shows port 80 instead of http).
  • -F — output in a script-friendly format (each line is a field, prefixed with an identifier character).
  • -t — output only PIDs (useful for piping to other commands like kill).

Example of a fast and clean check of listening ports:

sudo lsof -i -s tcp:listen -n -P

Step 9: Practical Example — Stopping a Process Blocking a Port

Suppose you start a web server on port 8080 and get an Address already in use error.

  1. Find the culprit:
    sudo lsof -i :8080
    

    In the output, look for the PID (e.g., 12345) and COMMAND (e.g., java).
  2. Stop the process (if it's not a critical service):
    sudo kill 12345
    

    If the process does not respond to SIGTERM (a normal kill), use force termination:
    sudo kill -9 12345
    
  3. Restart your server. The port should now be free.

Step 10: Finding File Descriptor Leaks

If a process (especially a long-running one) opens many files and doesn't close them, it can lead to exhausting the system's limit (Too many open files).

  1. See how many descriptors a process has open:
    lsof -p <PID> | wc -l
    

    (The COMMAND line is also counted, but this is sufficient for an order-of-magnitude estimate).
  2. See the top processes by number of open files:
    sudo lsof | awk '{print $2}' | sort | uniq -c | sort -nr | head -20
    

    This command:
    • awk '{print $2}' — extracts the second column (PID).
    • sort | uniq -c — counts occurrences of each PID.
    • sort -nr — sorts by descending count.
    • head -20 — shows the top 20.

Verifying the Result

After running any lsof command, check that the output contains the expected data:

  • For a file search: The NAME column should show your path.
  • For a port search: The NAME column should show *:port or IP:port, and TYPE should be IPv4 or IPv6.
  • For a PID search: The specified PID should be present in the list.

If the output is empty, it means the corresponding resources are not open (the file is not in use, the port is not being listened on) or you ran the command without sudo and cannot see other users' processes.

Common Issues

Issue 1: lsof: command not found

Cause: The package is not installed. Solution: Install it using your distribution's package manager (see Requirements).

Issue 2: Empty output when searching for a port (sudo lsof -i :80 shows nothing)

Cause 1: No process is actually listening on that port. The port is free. Cause 2: You are searching for an IPv6 port, but the process is listening on IPv4 (or vice versa). Try sudo lsof -i -P -n | grep :80 for a general search. Cause 3: The port is in a TIME_WAIT state (a closed connection that hasn't fully released yet). lsof does not show such sockets by default. Use netstat -an | grep :80 or ss -ltnp for a more complete picture.

Issue 3: permission denied or insufficient privileges

Cause: You are trying to view open files for a process owned by another user (especially root) without sudo. Solution: Always use sudo for a system-wide view: sudo lsof.

Issue 4: The lsof command runs very slowly

Cause: Using the +D option on a large directory or filtering by a complex pattern. Solution:

  • Avoid +D on root directories (/, /home). Search for specific files.
  • Use more precise filters (-p, -u, -c) to reduce the volume of data processed.
  • Add -n and -P to disable name resolution (speeds up execution).

Issue 5: Cannot delete a file, even though lsof doesn't show it being used

Cause 1: The file is deleted but still open by a process. In lsof, such a file will appear with (deleted) at the end of the NAME line. The process continues writing to this already deleted file descriptor, occupying disk space. Solution: Stop the process (kill) that holds the descriptor. Disk space will be freed automatically after the process terminates. Cause 2: The file is used by the kernel (e.g., as a swap file or the root of a mounted filesystem). lsof might not show such system-level usage. Use fuser -v /path/to/file or lsof /path/to/file | grep -v '(deleted)' for cleaner output.

F.A.Q.

What is lsof and what is it used for?
Why does lsof return 'command not found'?
How to find which process is listening on a specific port (e.g., 80)?
How does lsof differ from netstat or ss?

Hints

Installation and Availability Check
Basic Syntax and Viewing All Open Files
Finding Files Opened by a Specific Process
Finding Processes That Opened a Specific File or Directory
Finding the Process Listening on a Network Port
Filtering by Protocol (TCP/UDP) and State
FixPedia

Free encyclopedia for fixing errors. Step-by-step guides for Windows, Linux, macOS and more.

© 2026 FixPedia. All materials are available for free.

Made with for the community