-1

So I was writing a python script and my goal was to use lsof to list all open files under a specific directory (my home folder) for the local user and only output the 'uniq' entries.

My script looked like this:

import os, sys, getpass
user = getpass.getuser()
cmd = "lsof -u " + user + " +d ~ | sort | uniq"
os.system(cmd)

This kind of does what I want it to do, it does lsof for the current local user, but it fails to look specifically in the home directory that i specified. Instead it does lsof on the root directory and lists all lsof for the entire file system for the user. However, when I do the same command without the -u user it looks specifically in the home directory. I've been looking into why this is exactly, and yes I have tried using +d /home/ and +d ~/home/ instead of just +d ~ to get this to work with no success, so I am kind of stumped. Any advice would be great :)

user1634609
  • 59
  • 1
  • 3
  • 1
    Why would you expect `+d /home/` or `+d ~/home/` to do anything similar to `+d ~`? Normally, `~` is going to refer to something like `/home/me`, not just `/home`, and you're unlikely to have any files open in `/home` except maybe `/home/me`. (Note that `+d` is not recursive—use `+D` if you want that.) And `~/home/` will be `/home/me/home/`, which probably doesn't even exist. So, what were you trying to accomplish by trying them? – abarnert Feb 13 '13 at 20:35

2 Answers2

0

From the man page:

Normally list options that are specifically stated are ORed - i.e., specifying the -i option without an address and the -ufoo option produces a listing of all network files OR files belonging to processes owned by user ''foo''.

There are some exceptions, but none of them apply in your case.

So, -u me +d ~ means "all files that are opened by me OR in my home directory.

So how you do what you want?

The -a option may be used to AND the selections. For example, specifying -a, -U, and -ufoo produces a listing of only UNIX socket files that belong to processes owned by user ''foo''.

Throw a -a in there:

cmd = "lsof -a -u " + user + " +d ~ | sort | uniq"

By the way, in general, you really don't want to use os.system in Python, which is why the documentation specifically says:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

And really, why use sort and uniq instead of sorting in Python? Or, alternatively, if all you want to do is get this shell pipeline run, and not process it in any way in Python, why use Python instead of bash in the first place?

abarnert
  • 354,177
  • 51
  • 601
  • 671
0

lsof joins options together using OR by default, try adding the -a flag to AND them together.

LazyMonkey
  • 517
  • 5
  • 8