The lsof
command (LiSt Open Files) by default shows all types of file descriptors including:
- Regular files on disk
- Directories
- Block/character devices
- Pipes and FIFOs
- Network sockets (UNIX/TCP/IP)
- Shared memory segments
The most precise method uses lsof's field output (-F) with grep filtering:
lsof -Fn | grep -E '^n/.+' | cut -c2- | sort -u
This works because:
-Fn
makes lsof output only the name field- We grep for lines starting with 'n' (name indicator)
cut
removes the leading 'n' charactersort -u
provides unique results
To specifically target regular files (type REG):
lsof -F n | awk -F'\0' '$1 ~ /^f.*REG/ {print substr($2,2)}'
Or using the -l
flag for login names instead of UIDs:
lsof -l -F n | grep -B1 'REG' | grep -v 'REG' | cut -c2-
Combine with process selection:
# Files opened by Apache
lsof -c httpd -Fn | grep -E '^n/.+' | cut -c2-
# Files opened by user 'mysql'
lsof -u mysql -Fn | grep -E '^n/.+' | cut -c2-
For large systems, add filters early to reduce processing:
lsof -Fn -r 1 -u www-data | grep -E '^n/.+' | cut -c2-
The -r 1
makes lsof run continuously with 1-second delay between runs.
To find physical files marked as deleted but still held open:
lsof -Fn | grep -B1 'DEL' | grep -E '^n/.+' | cut -c2-
When troubleshooting disk space issues or auditing file access, you often need to focus strictly on physical files while excluding sockets, pipes, and network connections from lsof
output. The default output mixes all file types, making analysis cumbersome.
Here are three precise ways to filter lsof
output for physical files only:
Method 1: Using -F and grep
lsof -Fn | grep -E '^n/' | sed 's/^n//' | sort -u
Method 2: Filtering by File Type
lsof -F | awk -F' ' '$4 ~ /REG/ {print $0}'
Method 3: Combining Filters
lsof -F n | grep -v "TCP\|UDP\|unix" | awk -F'/' '/^\// {print $0}'
For real-world scenarios, consider these practical applications:
Finding Large Physical Files
lsof -Fn -s | grep -E '^n/|^s/' | awk '/^n/ {file=$0} /^s/ {size=$0; print file, size}' | sort -k2 -n
Monitoring Specific Processes
lsof -p $(pgrep nginx) -F n | grep -E '^n/' | sed 's/^n//' | sort -u
When working with thousands of open files:
- Pipe output to
head
during testing - Use
-n
to disable DNS resolution - Combine with
grep -v
for faster exclusions
Common issues and solutions:
- If seeing empty output, try
sudo lsof
- For binary files, add
-b
to avoid hangs - Use
-V
for verbose error reporting