I'm working on an application that monitors the processes' resources and gives a periodic report in Linux, but I faced a problem in extracting the open files count per process.
This takes quite a while if I take all of the files and group them according to their PID and count them.
How can I take the open files count for each process in Linux?
You could do ls -1 /proc/176909/fd | wc -l . ls -1 /proc/176909/fd puts every listed item out on a separate line in one column. wc -l counts the number of lines. So this would give you the total number of items in that directory.
Linux systems limit the number of file descriptors that any one process may open to 1024 per process.
A process has three file descriptors open by default, denoted by 0 for stdin, 1 for stdout, and 2 for stderr.
Have a look at the /proc/
file system:
ls /proc/$pid/fd/ | wc -l
To do this for all processes, use this:
cd /proc for pid in [0-9]* do echo "PID = $pid with $(ls /proc/$pid/fd/ | wc -l) file descriptors" done
As a one-liner (filter by appending | grep -v "0 FDs"
):
for pid in /proc/[0-9]*; do printf "PID %6d has %4d FDs\n" $(basename $pid) $(ls $pid/fd | wc -l); done
As a one-liner including the command name, sorted by file descriptor count in descending order (limit the results by appending | head -10
):
for pid in /proc/[0-9]*; do p=$(basename $pid); printf "%4d FDs for PID %6d; command=%s\n" $(ls $pid/fd | wc -l) $p "$(ps -p $p -o comm=)"; done | sort -nr
Credit to @Boban for this addendum:
You can pipe the output of the script above into the following script to see the ten processes (and their names) which have the most file descriptors open:
... done | sort -rn -k5 | head | while read -r _ _ pid _ fdcount _ do command=$(ps -o cmd -p "$pid" -hc) printf "pid = %5d with %4d fds: %s\n" "$pid" "$fdcount" "$command" done
Here's another approach to list the top-ten processes with the most open fds, probably less readable, so I don't put it in front:
find /proc -maxdepth 1 -type d -name '[0-9]*' \ -exec bash -c "ls {}/fd/ | wc -l | tr '\n' ' '" \; \ -printf "fds (PID = %P), command: " \ -exec bash -c "tr '\0' ' ' < {}/cmdline" \; \ -exec echo \; | sort -rn | head
Try this:
ps aux | sed 1d | awk '{print "fd_count=$(lsof -p " $2 " | wc -l) && echo " $2 " $fd_count"}' | xargs -I {} bash -c {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With