LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Need an lternative for lsof command (https://www.linuxquestions.org/questions/linux-newbie-8/need-an-lternative-for-lsof-command-888092/)

hk_centos 06-24-2011 06:46 AM

Need an lternative for lsof command
 
Hi,

In my bash script I need to move files in a folder if it is not in use.

Code:

for entry in `ls /root/shared_storage/input`; do

                echo $entry
                run=`lsof /root/shared_storage/input/$entry`
                ru=${run:0:5}
                echo $entry

                if [ "$ru" == "" ]; then
                    ........

It worked fine sometimes but sometimes it just get stuck at lsof.
Is there any other way that I can use here to check if the $entry is using some other process?
Or am I using this wrong?

Appriciate your ideas :)

theNbomr 06-24-2011 09:16 AM

Not sure what you mean by 'it worked'. According to my logic, the variable '$ru' can only ever get the value 'COMMA'.

You don't need the initial 'ls' command:
Code:

for entry in /root/shared_storage/input/*; do
If the filename in '$entry' contains whitespace, it will cause lsof to fail, so enclose the filespec in quotes:
Code:

run=$(lsof "$entry")
Note also the use of the '$( .... )' notation which is preferred over `backticks`.

On any files/directories that I tried, lsof always reports with a heading line:
Code:

COMMAND    PID USER  FD  TYPE DEVICE SIZE/OFF    NODE NAME
, so the result of the bash substring extraction is always 'COMMA'.

What is this intended to accomplish? It isn't obvious to me from the given context.
An alternative algorithm might be to parse the output of lsof (no args).

--- rod.

hk_centos 06-24-2011 10:56 PM

Hi,

I don't need the output of lsof, what I need to know is if the file $entry is using by another process.
If it is in use it lsof gives out something otherwise nothing. When I catch the output of lsof to $run & compare it to be empty in if statement it tells something string too long. That's the only purpose of $ru value.
If $entry not in use it should be moved to somewhere else.

Hope I explained clear now & you can help me..
Thanks!

Tinkster 06-24-2011 11:18 PM

So your problem is that sometime lsof won't return "at all"?
It just hangs, and your loop doesn't get executed?

Btw, you wouldn't really need to capture any output:
Code:

for entry in /root/shared_storage/input/*;
do
        if lsof $entry >/dev/null 2>&1; then



Cheers,
Tink

hk_centos 06-24-2011 11:51 PM

Quote:

Originally Posted by Tinkster (Post 4395128)
So your problem is that sometime lsof won't return "at all"?
It just hangs, and your loop doesn't get executed?

Btw, you wouldn't really need to capture any output:
Code:

for entry in /root/shared_storage/input/*;
do
        if lsof $entry >/dev/null 2>&1; then



Cheers,
Tink

Exactly!
It just hungs there at lsof (doesn't print the 2ns $entry in code).

Do you know why it happens?
Any solutions for that?

Tinkster 06-25-2011 12:09 AM

I've seen lsof take its time, I never saw it fail ... on such an
occasion where it fails, can you check with strace what it's doing?

strace -vFf -o ~/lsof.out -p <lsof PID>


If you don't want to go down the route of finding out why lsof
is failing, you could use "fuser" instead.
Code:

for entry in /root/shared_storage/input/*;
do
        if fuser $entry >/dev/null 2>&1; then



Cheers,
Tink

theNbomr 06-29-2011 09:30 AM

Quote:

Originally Posted by hk_centos (Post 4395121)
Hi,

I don't need the output of lsof, what I need to know is if the file $entry is using by another process.
If it is in use it lsof gives out something otherwise nothing. When I catch the output of lsof to $run & compare it to be empty in if statement it tells something string too long. That's the only purpose of $ru value.
If $entry not in use it should be moved to somewhere else.

Hope I explained clear now & you can help me..
Thanks!

So, why not just grep the output of lsof?
Code:

for entry in /root/shared_storage/input/*; do
    lsof | grep "$entry"
    if [ $? -eq 0 ]; then
        echo Found $entry
    fi

--- rod.

Tinkster 06-29-2011 12:41 PM

Quote:

Originally Posted by theNbomr (Post 4399170)
So, why not just grep the output of lsof?
Code:

for entry in /root/shared_storage/input/*; do
    lsof | grep "$entry"
    if [ $? -eq 0 ]; then
        echo Found $entry
    fi

--- rod.

That's even worse :}

His problem is that sometimes lsof doesn't return. That will be
the same (or worse) if he gets ALL open files, and greps for the
entry. Plus it would increase the runtime if it runs to completion.


Cheers,
Tink

theNbomr 06-29-2011 03:26 PM

It seems probable to me that the argument being passed to lsof has something to do with why lsof is misbehaving. Running it without any argument gets around that. It could be run once only, the output saved to a file, and the file parsed iteratively for each of the files in the specified directory. It may require a bit more careful parsing that my simple example, but that is a minor change dictated by the purpose. I just don't buy that lsof is somehow broken. I'm not saying that using fuser isn't a reasonable approach to the problem; rather that the way in which lsof was used by the OP seems suboptimal.

--- rod.

Tinkster 06-29-2011 03:45 PM

If lsof doesn't return when invoked w/ a file/directory path as
an argument it's broken as far as I'm concerned. The only valid
reason for it to fail would be that a mountpoint/fs has become
unavailable, e.g., an NFS share went down, an HDD died. In these
cases an invocation w/o parameters would fail in the same way: it
just won't return.



Cheers,
Tink

hk_centos 07-03-2011 01:57 AM

Quote:

Originally Posted by Tinkster (Post 4399524)
If lsof doesn't return when invoked w/ a file/directory path as
an argument it's broken as far as I'm concerned. The only valid
reason for it to fail would be that a mountpoint/fs has become
unavailable, e.g., an NFS share went down, an HDD died. In these
cases an invocation w/o parameters would fail in the same way: it
just won't return.



Cheers,
Tink

Hey Tink you are great! the directory /root/shared_storage/ contains some directories mounted to NFS. And moving input directory to /root/ almost solved the problem. :)

Thanks a million to you all for making me like Linux!!


All times are GMT -5. The time now is 07:30 PM.