Loading date…
LinkedIn Twitter Instagram YouTube WhatsApp
Malwarebytes - Cybersecurity for Everyone

Linux lsof Command Cheat Sheet: 75 Commands for SOC Analysts

Terminal window showing the Linux lsof command listing open ports, processes, and deleted files for incident response

Linux lsof Command Cheat Sheet: Find Suspicious Processes, Open Ports, and Deleted Files

Last verified: October 26, 2026 (syntax checked against current lsof documentation behavior).

It was 2:14 a.m. when the alert fired: root volume at 100% on a production log server. The on-call engineer ran du on every directory he could think of and the numbers added up to barely 40% of the disk. Nothing was missing, nothing was growing, and yet the filesystem insisted it was full.

Sponsored
root@kali:~# lsusb
Best Adapters for Kali Linux
Wi-Fi adapters for your pentesting lab
Shop Now →
As an Amazon Associate, I earn from qualifying purchases. This costs you nothing extra.

The culprit turned out to be a rotated log file that had been deleted while a running service still held it open. The space was never released. One command found it in about three seconds: lsof +L1.

That is the real value of lsof. It answers the question "what is this process actually touching right now?", and in Linux incident response that question comes up constantly, whether you are chasing a disk-space ghost, an unexpected listener on a high port, or a process that has no business reading your SSH config. This guide walks through the lsof commands that matter most for SOC analysts and sysadmins, grouped by the investigation they support.

Table of Contents

What lsof Actually Shows You

lsof stands for "list open files." On Linux, nearly everything is a file: regular files, directories, network sockets, pipes, devices. So lsof doubles as a process-to-resource mapping tool. One caveat: it shows what a process has open right now. It is not a history of everything a process has ever accessed, so a file that was opened and closed a second ago will not appear.

A typical line of output has these columns: COMMAND, PID, USER, FD, TYPE, DEVICE, SIZE/OFF, NODE, and NAME. The two columns worth learning first are FD and TYPE.

Column / ValueMeaning
FD: cwdThe process's current working directory
FD: txtThe executable itself
FD: memMemory-mapped file, such as a shared library
FD: 4u, 5r, 6wDescriptor number plus mode: read, write, or read/write
TYPE: REG / DIRRegular file / directory
TYPE: IPv4 / IPv6Internet socket
TYPE: unix / FIFOUnix domain socket / named pipe

The One Gotcha: OR vs. AND Filtering

This trips up even experienced admins. By default, lsof treats multiple selection options as alternatives (logical OR). Run lsof -u alice -i and you get everything alice has open plus every Internet socket on the system, not just alice's sockets. Add -a to require all conditions to match (logical AND).

sudo lsof -a -u alice -i

What it does: lists only Internet sockets owned by user alice. When to use it: any time you combine filters, such as user plus network, PID plus port, or PID plus file descriptor. Expected output: a short list of alice's TCP/UDP sockets rather than a screen-flooding dump.

Process, User, and File Lookups

Start here when you have a suspect: a PID from top, a username from an auth log, or a file you care about.

Investigating by process

lsof -p 1234
lsof -p 1234,5678
sudo lsof -R -p 1234
sudo lsof -g 5678
lsof -p $$

These show everything one PID (or several) has open. -R adds the parent PID column where supported, which helps when you are tracing a child process back to the thing that spawned it. -g selects by process group ID, and $$ expands to your current shell's PID, which makes it a handy way to see what lsof output looks like on a process you control. Expect a table with the executable, libraries, working directory, and any open files or sockets.

Investigating by user or command name

lsof -u alice
lsof -u 1001
lsof -u ^alice
lsof -c nginx
sudo lsof -c python
sudo lsof -c java

Use -u with a username or numeric UID to see what an account is touching. The caret (^) inverts the selection, so -u ^alice shows everyone except alice, which is useful for filtering out your own noise. -c matches processes whose command name begins with the string, so -c python also catches python3. Keep in mind that a process can rename itself, so treat command names as a lead, not proof.

Who is using this file or directory?

sudo lsof /var/log/syslog
sudo lsof /etc/ssh/sshd_config
sudo lsof +d /var/log
sudo lsof +D /var/www
sudo lsof +D /media
sudo lsof /dev/sda
sudo lsof +f -- /mnt/data

Passing a path directly returns every process holding that file open. This is the command to run before log rotation, before unmounting a drive (the classic "target is busy" error), or when checking whether anything unexpected has your SSH config open. The difference between the two directory flags matters: +d looks only at files directly inside the directory, while +D walks the whole tree. On a large web root or a busy log directory, +D can take a long time and generate real I/O, so avoid it on a production host during peak load. The +f -- form tells lsof to interpret the path as a filesystem, so you get every open file on that mount.

Network Connections and Ports: Linux Threat Hunting Basics

For Linux threat hunting on a single host, network-focused lsof is often faster than reaching for a full packet capture. Always add -nP: it stops lsof from resolving hostnames and port names, which makes output faster and prevents you from misreading a port because it was translated into a service name.

Inventory listeners and connections

sudo lsof -nP -i
sudo lsof -nP -iTCP -sTCP:LISTEN
sudo lsof -nP -iTCP -sTCP:ESTABLISHED
sudo lsof -nP -iUDP
sudo lsof -i4
sudo lsof -i6
sudo lsof -U

What they do: list all Internet sockets, only listening TCP sockets, only established TCP sessions, UDP sockets, IPv4-only, IPv6-only, and Unix domain sockets respectively. When to use them: the LISTEN query is your baseline "what is this server exposing?" check. The ESTABLISHED query shows live conversations. Expected output: rows like sshd 812 root 3u IPv4 ... TCP *:22 (LISTEN). Run these as root for full visibility, because as a normal user you will only see your own processes.

Pinpoint a port, host, or range

sudo lsof -nP -iTCP:80
sudo lsof -nP -iTCP:443
sudo lsof -nP -i :8080
sudo lsof -nP -iUDP:53
sudo lsof -nP -iTCP:8000-8100
sudo lsof -nP -i @192.0.2.10
sudo lsof -nP -iTCP@192.0.2.10:443
sudo lsof -t -i :8080
sudo lsof -a -p 1234 -i
sudo lsof -a -p 1234 -iTCP:443

These answer "which process owns this port?" and "which process is talking to that address?" The -t variant prints only PIDs, which is ideal for scripting but returns multiple PIDs when several processes match. The addresses above use the documentation range 192.0.2.x, so substitute a real address. When an endpoint detection and response (EDR) alert gives you only an IP and port, this is how you map it back to a local process in seconds.

File Descriptors and File Types

lsof -a -p 1234 -d 0-2
lsof -a -p 1234 -d 5
lsof -a -p 1234 -d 3,4,5
lsof -p 1234 | grep REG
lsof -p 1234 | grep DIR
lsof -p 1234 | grep mem
lsof -p 1234 | grep PIPE

The -d flag filters by descriptor. Descriptors 0, 1, and 2 are standard input, output, and error. That matters in investigations: if a long-running daemon has stdin or stdout pointing at a network socket instead of /dev/null, that is worth a closer look, because it is a pattern associated with remote shells (a hypothesis to verify, not a verdict). The grep variants simply slice the normal output by TYPE, so you can separate libraries (mem) from data files (REG) and inter-process plumbing (PIPE). A process loading a library from /tmp or another world-writable path is the sort of finding that deserves follow-up.

Deleted Files and Disk Space Investigation

Back to the 2 a.m. page. When a file is deleted while a process still has it open, Linux keeps the data on disk until the last descriptor closes. The file vanishes from ls and du, but df still counts the space.

sudo lsof +L1
sudo lsof +L1 | grep -i log
sudo lsof -a -p 1234 +L1
sudo lsof -a -u alice +L1

What it does: +L1 selects open files with a link count below one, which in practice means deleted-but-still-open files. When to use it: whenever df and du disagree. Expected output: rows with a NLINK of 0 and a NAME ending in (deleted), along with the PID holding the space. The log-focused grep usually surfaces the culprit immediately, and the -a variants narrow it to one process or user.

Before rotating logs or unmounting storage, check who has the target open:

sudo lsof /var/log/syslog
sudo lsof +f -- /var

The usual fix for the disk-space case is to restart or reload the owning service so it releases the descriptor. Do that during an approved maintenance window, because restarting a production service has its own consequences.

Forensic note: a deleted file that a process still holds can often be read through /proc/<PID>/fd/<N>. If that file might be evidence, such as a deleted binary or a wiped log, copy it somewhere safe first and document what you did. Do not truncate it to reclaim space until you are sure you will not need it. Truncation is destructive and unrecoverable.

Real-World Scenario: The Unknown Listener

Here is a composite scenario, typical of what SOC teams encounter. A vulnerability scan flags an unexpected listener on TCP port 4444 of a Linux web server. Nobody on the team recognizes it.

  1. Identify the owner. Run sudo lsof -nP -iTCP:4444. The output shows a process named php-fpm listening on all interfaces, which is odd because the real php-fpm only talks over a Unix socket on this host.
  2. Inspect the process. Run sudo lsof -R -p <PID> to see its parent and its open files. If the txt entry points to a path in /tmp or shows (deleted), the executable was removed after launch, a common technique to hinder analysis.
  3. Check descriptors 0-2. sudo lsof -a -p <PID> -d 0-2 reveals whether standard streams are tied to a socket.
  4. Look at connections. sudo lsof -a -p <PID> -i shows any outbound sessions.
  5. Preserve before you kill. Capture the lsof output to a file, record the PID, user, and start time, and copy the binary via /proc/<PID>/exe if policy allows. Only then isolate the host according to your incident response plan.

Notice what lsof gave you: the owner, the parent, the executable's state, and the network exposure, all without installing anything. It will not tell you how the process got there. Pair it with auth logs, web server logs, and file integrity data to reconstruct the entry point. Treat the analysis above as a hypothesis until those sources confirm it.

Output, Reporting, and Monitoring

sudo lsof -r 5 -i
sudo lsof -r -i
sudo lsof > lsof-report.txt
sudo lsof -nP -i > network-sockets.txt
sudo lsof -p 1234 >> process-files.txt
sudo lsof | wc -l
sudo lsof | grep -F 'config.json'
sudo lsof -Fpcfn -p 1234

Repeat mode: -r 5 re-runs the listing every 5 seconds, and -r alone uses the default interval (15 seconds); both continue until you press Ctrl+C. It is a lightweight way to watch a connection appear and disappear during triage.

Reports: the redirect examples save a point-in-time snapshot. Timestamp your files, since a snapshot without a time is hard to use later. >> appends instead of overwriting.

Counting and searching: wc -l gives a rough total of lines. On modern systems, thread entries and the header row inflate that number, so treat it as a trend indicator, not an exact count of open files. grep -F does a fixed-string search, which avoids regex surprises with dots and special characters in filenames.

Machine-readable output: -F with field letters (here p PID, c command, f descriptor, n name) prints one field per line, each prefixed with its code. That is much safer to parse in scripts than splitting on whitespace, but you must interpret the field codes correctly, so check the manual for your build.

Help and version:

man lsof
lsof -h
lsof -v

The manual is long but excellent. -h prints a short usage summary, and -v prints version and build details, where supported. Different distributions ship slightly different builds, so check these before assuming a flag exists.

Detection and Hardening Notes

  • Baseline your listeners. Save the output of sudo lsof -nP -iTCP -sTCP:LISTEN on known-good servers. Comparing against it later turns "is this normal?" into a diff.
  • Watch for deleted executables. A running process whose binary shows as (deleted) is not automatically malicious (package updates can cause it), but it deserves a look, especially on hosts that were not just patched.
  • Review unexpected descriptors. Interpreters such as Python or Java holding sockets or files outside their application directory may be legitimate, or may not. Check against the application's documented behavior.
  • Restrict who can see everything. Full visibility requires root, so limit sudo access and log its use. Audit tooling such as auditd can record who ran what.
  • Know the blind spots. Containers, namespaces, hidepid mount options, and kernel settings change which processes and sockets lsof can see. A host-level lsof may not show the inside of a container, and a sophisticated rootkit can interfere with any user-space tool. No single command gives you guaranteed visibility.
Sponsored
root@kali:~# lsusb
Best Adapters for Kali Linux
Wi-Fi adapters for your pentesting lab
Shop Now →
As an Amazon Associate, I earn from qualifying purchases. This costs you nothing extra.

For teams evaluating endpoint detection and response tools, lsof is a good reminder of what good telemetry looks like: process, parent, file, and socket in one view. EDR platforms collect this continuously, while lsof gives you the same kind of snapshot by hand when the agent is missing or you need a quick second opinion.

Expert Tips

  • Always use -nP on network queries. It is faster, avoids DNS lookups that leak your investigation, and removes naming ambiguity.
  • Run as root, but know why. Without sudo you will see a partial picture and may wrongly conclude a port is unused.
  • Prefer -t for scripts, but print before acting. Never pipe lsof -t directly into kill without reviewing the PIDs first. A broad match can terminate the wrong service.
  • Avoid +D on huge trees. Use +d or point at a specific file first.
  • Save evidence first. Redirect output to a timestamped file before you change anything on a suspect host.
  • Cross-check with other tools. Compare lsof results with ss -tulpn and ps. Disagreements between tools are themselves a finding.

FAQ

What does the lsof command do in Linux?

It lists files that running processes currently have open, including regular files, directories, network sockets, pipes, and devices. It is widely used to map a file or port back to the process using it.

How do I find which process is using a port?

Run sudo lsof -nP -i :8080, replacing 8080 with your port. Add -t if you only want the PID.

Why does lsof show nothing for some processes?

Usually permissions. Without root you can only see your own processes. Containers, namespaces, and kernel hardening options can also limit visibility.

What is the difference between +d and +D?

+d examines only files directly inside the named directory, while +D searches it recursively. The recursive form can be slow and I/O heavy on large trees.

How do I find deleted files that are still using disk space?

Use sudo lsof +L1. It lists open files with a link count below one, typically deleted files held open by a running process. Restarting or reloading the owning service releases the space.

Why did lsof -u alice -i show more than alice's sockets?

Selection options are ORed by default. Add -a (lsof -a -u alice -i) to require both conditions.

Is lsof better than netstat or ss?

They overlap. ss is faster for pure socket statistics, while lsof shines when you need to see everything else a process has open alongside its sockets. Using both is good practice.

Conclusion

lsof rewards the habit of asking "what is this process really doing?" It solves mundane problems, like the full disk with no visible files, and serious ones, like an unexplained listener on a production server. Learn the filtering logic (especially -a), make -nP a reflex, keep a baseline of normal listeners, and capture output before you change anything. Combined with logs and EDR telemetry, a handful of lsof commands will resolve a surprising share of your investigations quickly.

Analysis based on SOC monitoring experience and review of public Linux documentation. Replace example PIDs, usernames, hosts, and paths with real values, and test on non-production systems first.

Shubham Chaudhary

Shubham Chaudhary is a cybersecurity specialist and founder of Xpert4Cyber. He shares practical tutorials, guides and the latest news on Networking, Windows Server, Linux Server, Ethical Hacking, Digital Forensics, Malware Analysis, Threat Hunting and Monitoring, OSINT, Cloud Computing and AI, with a focus on defense and security awareness. Educational and defensive use only.

Post a Comment

Previous Post Next Post