41

On Linux, ulimit -n can be used to change or view the limit on the number of file descriptors for a process, and lsof -p nnn | wc -l seems to consistently report the actual file descriptor usage.

But on Mac OS X, lsof -p nnn | wc -l can return a number higher than the limit. I suppose this means lsof is returning more than just file descriptors, but I can't tell what's what.

Bottom line: How can I get an accurate count of file descriptor usage in Mac OS X?

Zearin
  • 1,474
  • 2
  • 17
  • 36
jfklein
  • 877
  • 1
  • 11
  • 13
  • 1
    To start, don't pipe the output and see what it's actually listing. Then you'll have an idea of where those extra descriptors are coming from and what they are. – Jason Coco Apr 27 '09 at 21:03

4 Answers4

49

I came across the need for identifying this recently - the command I used to count up the total entries (so more than just file handles, but it's relative so therefore relevant in my opinion) is:

lsof | awk '{print $1}' | sort | uniq -c | sort -rn | head

This gives something like the following output (your highest-used applications may be different!):

$lsof | awk '{print $1}' | sort | uniq -c | sort -rn | head
1259 Google
 682 Code\x20H
 369 Spotify
 334 VLC
 322 cloudd
 303 corespotl
 278 com.apple
 273 UserEvent
 249 GitHub
 176 Slack\x20

I usually only need to see the top 10 entries, but you can manipulate head to show as many lines as you like (e.g., head -n 40).

Nicolas Bouvrette
  • 4,295
  • 1
  • 39
  • 53
keba
  • 2,027
  • 2
  • 16
  • 20
11

lsof can show a lot of things beyond just file descriptors, but most of what is likely inflating your count is the loaded frameworks and libraries for an application. You can look at the "FD" column to see if a line is a file descriptor--in which case it's a number, possibly followed by a letter indicating the mode--or something else (see the description of the FD column in the lsof man page for the full list).

If you just need a rough approximation adding a 'grep -v " txt "' before your wc will get you a lot closer to an accurate value. If you need an exact value, you probably need to put together a regex to feed the output through that filers precisely by the FD column.

smorgan
  • 20,228
  • 3
  • 47
  • 55
5

I modified anders' answer, now it only displays the opened fd numbers of a specific process:

FCOUNT=`lsof -p $1 | grep -v " txt " | wc -l`;echo "PID: $1 $FCOUNT" | sort -nk3

Example:

$ ./fd-count.sh 5926                                                                                                           
PID: 5926       97
laike9m
  • 18,344
  • 20
  • 107
  • 140
  • If it matters to anyone, the count is off by one because `lsof -p $1` will print a header row in addition to the list of file descriptors. – Aaron May 04 '18 at 01:10
3

I was looking for which process that had lots of file descriptors - so I guess something like

for pid in `ps aux | tail -n +2 | awk '{print $2}'`; do FCOUNT=`lsof -p $pid | grep -v " txt " | wc -l`; echo "PID: $pid $FCOUNT"; done | sort -nk3
Aaron
  • 3,209
  • 1
  • 12
  • 14
anders.norgaard
  • 1,062
  • 13
  • 23
  • `lsof: illegal process ID: PID` – bithavoc Jan 12 '15 at 15:31
  • 1
    @bithavoc, use for pid in `ps aux | tail -n +2 | awk '{print $2}'`; do FCOUNT=`lsof -p $pid | grep -v " txt " | wc -l`; echo "PID: $pid $FCOUNT"; done | sort -nk3 -- This will cut off the first row of ps output which contains column headers. – VladLosev Jan 21 '15 at 22:50
  • You should also add the `| tail -n +2` trick to the `lsof -p $pid | grep -v " txt " | wc -l` so that you don't end up counting the header row as a file descriptor. – Aaron May 04 '18 at 01:21