
A Unix Utility to Know About: lsof (2009) - kercker
http://www.catonmat.net/blog/unix-utilities-lsof/
======
nailer
For finding what uses a file, I'm an 'fuser' kid but lsof is fine too. Using
posh right now, so had to make my own:

    
    
        function fuser($relativeFile){
          $file = Resolve-Path $relativeFile
          foreach ( $Process in (Get-Process)) {
            foreach ( $Module in $Process.Modules) {
              if ( $Module.FileName -like "$file*" ) {
                $Process | select id, path
              }
            }
          }
        }
    

In use:

    
    
        > fuser .\node_modules\
    
          Id Path
          -- ----
        2660 C:\Program Files\nodejs\node.exe
    

Since it's object pipelining, you can:

    
    
        > fuser .\node_modules\ | kill

~~~
smhenderson
I find myself using lsof for it's ability to show me what TCP sockets are in
use more than what actual files are open.

lsof | grep TCP

~~~
Terr_
For that I often use:

netstat --ip -a -p

Those particular options mean to show just IP ports (UDP/TCP), in all statuses
(active, listening) and to display the local process which is involved.

------
voidz
`lsof` and `ps` have the most dense man pages I have ever tried to plow
through, and that's causing me to use these tools only at a minimum.

~~~
johnchristopher
I am guilty of using `ps|aux` for the sole purpose of answering this question:
Is it (still) running ?

edit: `ps aux|grep`, indeed. Silly me in the early hours of a rest day :).

~~~
devonkim
Modern Linuxes have pgrep to help avoid the inevitable "lol, the grep process
I fired will match" issue that results in having to filter that out as well
with yet another program.

~~~
smhenderson
Yeah, I always felt having to type the extra bit was strange, like maybe grep
could have a switch to say "don't find grep" but I guess having a switch for
such a specific use case, grepping processes, is overkill.

Anyway, it's just a reflex now to always:

    
    
      ps aux | grep <program> | grep -v grep

~~~
amyjess
You can also surround each character in the program's name with square
brackets.

    
    
        ps -ef | grep [p][r][o][g][r][a][m]

~~~
smhenderson
Yes, I never knew that. But I saw it in another post and as the sibling post
mentions it's enough to surround just the first character with the brackets...

This is why I love HN, I learn stuff I never knew I wanted to know!

------
corford
_lsof -i -n -P_ is a regular "reflex" command whenever I'm trying to figure
out why a daemon I've just setup isn't responding to requests (immediately
answers the questions: is it running? and, if yes, under what privs? and on
what interface?).

That together with a dump of active iptables rules normally results in an
immediate fix for 90% of "why can't I connect to X" problems :)

~~~
alinspired
had to try this lsof to see it's essentially `netstat -atpu`

------
rconti
Most days, HN threads make me feel really dumb. On rare days, they make me
feel really smart.

------
newscracker
Although a bit rare in my usage, I have found basic use of lsof quite useful
when needed. I haven't even tried many command line options. The options it
provides really seem comprehensive. I have also found similar tools on Windows
(like WhoLockMe or Process Explorer) quite useful.

~~~
mxuribe
I'm not exposed to windows machines as much as i used to be, but yeah process
explorer was pretty cool.

------
amelius
What kernel functions does this command invoke to retrieve this information?
How could I write my own version of lsof?

~~~
b3h3moth
The stat() family functions for sure, BSD Sockets, user account, covering
everything from "process environement" to "filesystem" functions.

"FAQ about lsof"[1] is very instructive.

[1] ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ

------
_c_
s/Unix/Linux/

The following can be adapted to provide other information: whatever procfs
provides. This is a rough equivalent of "pgrep -fl .|less". _Work-in-
progress_. Don't know if Linux grep has "-a" option.

    
    
      #! /bin/sh 
      # Almquist clone, not Bash
     
      case $# in
      0)
      exec grep -a . proc/[0-9]*/cmdline \
      |exec tr '\000' '\040' \
      |exec sed '
                 /grep -a .* proc/d;
                 #parent: '"$$"';
                 s/proc./ /;
                 s/\/cmdline:/ /;
     ' \
      |exec less
      ;;
     
      *)
      exec grep -a . proc/[0-9]*/cmdline \
      |exec tr '\000' '\040' \
      |exec grep $@ \
      |exec sed '
                 /grep '"$@"'/d;
                 s/proc./ /;
                 s/\/cmdline:/ /;
     ' \
      |exec less
      esac

~~~
LukeShu
You don't need any of those `exec`s. Yes, GNU grep has `-a`.

If you don't like the backslash-newline-pipe sequence, if you put the pipe at
the end of the previous line, you don't need the backslash; but it's less
obvious that the next line is operating on the output of the previous.

Multi-line arguments to sed can be a pain (good luck getting your editor to
auto-indent them). Instead, you can use -e to specify multiple sed commands.

There's nothing in there that would make it not work in bash. That should work
in any Bourne-family shell.

It only handles 0 or 1 arguments correctly, not > 1.

~~~
_c_
Thanks for taking the time to comment.

Multiple arguments could be added if you want that. I personally do not need
it as I search the cmdline patterns I need without using spaces. I use dots
instead. Quick and dirty.

I write 100's of these small scripts for my own use only so I have my own
style, peculiar as it may be. I never _need_ indentation because I always keep
scripts short; I only use it occasionally and randomly.

I do not use -e with sed, unless I'm using branches or loops.

The execs seem superfluous but actually make a difference, at least on the
UNIX I use. Try it with and without and see if you notice.

All my scripts are portable to Bash, but they're also portable to the most
basic of Bourne-compatible shells too. I do not use Bash.

~~~
LukeShu
What shell are you using? I could see a naive shell forking twice without
exec, but I don't know of a shell that does that. Exec just says "don't
fork(3) before calling exec(3)", but, but inside of a pipeline like that, it
shouldn't fork again anyway. I have tried it with and without.

~~~
_c_
In theory it should not make a difference but my scripts _seem_ to run faster
when I use exec after pipe.

Normally I would only add exec to the last command in the script, as djb does.
But then I started experimenting with using it after pipes.

If you or anyone can explain why this could make scripts "seem" to execute
faster, I would be grateful.

Here's the shell source: ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-
release-7/src/bin/sh

Incidentally, have you ever tried execlineb? I use that sometimes too.

------
amyjess
lsof is my go-to command for "why won't this drive unmount?". That alone makes
it incredibly useful.

Also, back in the bad old days, 'lsof | grep snd' helped track down what the
hell was hogging my sound card (setting up proper mixing has made that a
distant memory, though).

~~~
cmiller1
lsof | grep Trash is super useful on os x when Finder refuses to empty the
trash because some process is holding onto one of the files.

------
0x0
You can save quite some time waiting for reverse dns lookups if you use "lsof
-n"

------
sreeramvenkat
I frequently use lsof to get the location of a log file created by a process.

something like,

lsof | grep <pid> | grep log

------
gkya
fstat(1) is similar on FreeBSD, lsof is in the ports.

