How to find the process with maximum file descriptors?

What is wrong with this for loop? I am trying to find which process has the maximum number of file descriptors. The first command in the for loop ps aux | awk '{print $2}' prints out only the process IDs. I know the first error lsof: illegal process ID: PID is there because the 1st line of the output is PID, but shouldn’t the loop work fine for the rest of the lines?

[[email protected] ~]# for i in `ps aux | awk '{print $2}'` ; do `lsof -p $i | wc -l` ; done
lsof: illegal process ID: PID
lsof 4.82
 latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
 latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
 latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
 usage: [-?abhlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[gG]] [+|-e s]
 [-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]
Use the ``-h'' option to get more help information.
-bash: 0: command not found
-bash: 22: command not found
-bash: 4: command not found
-bash: 4: command not found
-bash: 4: command not found
-bash: 4: command not found
^C
[[email protected] ~]#

Why is it executing the output of wc -l instead of going back to the loop?

Or is there another way I can find the process with maximum file descriptors?

Answer

The issue is the backticks in your do ... done section.

When writing shell script, you do not need to encapsulate blocks (if; then ... fi, while; do ... done, etc) in backticks. Doing so results in the shell evaluating the contents of the backticks, and then executing that content. So the backticks are returning a number (the number of open files), and then trying to run that number, resulting in a command not found.

Thus you want:

for i in `ps aux | awk '{print $2}'` ; do lsof -p $i | wc -l ; done

Leave a Reply

Your email address will not be published. Required fields are marked *