views:

225

answers:

4

I'm trying to test a single file if it is open using lsof. Is there a faster way than this?

$result = exec('lsof | grep filename | wc -l');

if($result > 0) {
    //file is open
}

I'm thinking their must be a way to just test for one file if you know the filename. All I really need is a true or false.

+1  A: 

Well, you can skip wc and use the return value of grep (grep returns 0 (i.e. success) if it detects the pattern and 1 (i.e. not-success) if it does not detect the pattern):

if lsof | grep filename > /dev/null; then
    # filename is in output of lsof
fi

You can improve this a bit by using grep's -l flag:

if lsof | grep -l filename > /dev/null; then
...

This tells grep to stop looking once it detects it's first match.

R Samuel Klatchko
If you actually care about the process that's using the file, better to use the `-m 1` option for grep so you actually get the matching line instead of the filename (stdin) the match was found in. (Otherwise, nice alternate use of `-l`.)
Jefromi
+3  A: 

I found a much better way. With lsof (tested on version 4.63), you can directly query a specific file:

if lsof filename > /dev/null; then
    # file is open
fi
R Samuel Klatchko
A: 

Use fuser. It returns non-zero if any of the files specified are in use, and zero if they're all available.

Marc B
+1  A: 

Don't. The answer might change by the time you try to do anything with the result. Instead, try to do whatever you intended to do with the file and handle the "in use" error or "sharing violation".

Ben Voigt
For you: +1, from what I'm seeing I think you might be right. Although your answer doesn't specifically answer the question.
jjclarkson
Jared Parsons has a nice write-up on why the question itself is fundamentally flawed: http://blogs.msdn.com/jaredpar/archive/2009/12/10/the-file-system-is-unpredictable.aspxIn such cases, it's best not to answer the question that WAS asked, but the question that SHOULD have been asked.
Ben Voigt