LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Server (https://www.linuxquestions.org/questions/linux-server-73/)
-   -   find . -type d |grep fuser (does not work, why) (https://www.linuxquestions.org/questions/linux-server-73/find-type-d-%7Cgrep-fuser-does-not-work-why-730244/)

thllgo 06-02-2009 04:27 PM

find . -type d |grep fuser (does not work, why)
 
if I run the command "find . -type d" it does what its supposed to, it find directories. If I try to pipe the output into fuser I get a response as if I just typed "fuser" by it self. Why?

I user fuser to find out what process is occupying a directory. This is useful if you are trying to unmount a dir. and get a busy error. The problem is fuser is not recursive.

colucix 06-02-2009 04:31 PM

You have to use xargs to execute commands on the arguments passed as standard input:
Code:

find . -type d | xargs fuser

pwc101 06-02-2009 04:34 PM

Maybe fuser can't read a list from standard input (as appears to be the case here); instead you'll need to supply the list of arguments to fuser. This can achieved with find as follows:
Code:

find ./ -type d -exec fuser {} +

thllgo 06-02-2009 04:39 PM

that worked, thanks.

avalonit 12-26-2011 03:00 PM

Actually this doesn't catch everything. Remove "type -d" and you catch more. But still you could be unable to umount due to FS being busy. In my case the filesystem is used as aufs overlay fs and it doesn't show up in fuser. I don't have lsof on that distro so can't tell if lsof is better.

David the H. 12-27-2011 08:59 AM

Just in case it's not perfectly clear, in the command above you're piping the stdout of find into the stdin of grep. So you have grep searching for the literal string "fuser" in the text output of find; you're searching the file names, not the contents of the files themselves.

If you tried piping it directly into fuser you'll simply get an error, because as pwc101 points out, fuser doesn't read from stdin.

What you really want to do is execute the fuser command once for each name found. As demonstrated, find's -exec option or xargs are common ways to do it.

It's also possible to use a bash loop like this:

Code:

while IFS="" read -r -d "" dir; do
        fuser "$dir"
done <( find . -type d -print0 )

http://mywiki.wooledge.org/BashFAQ/001

Or if you're using bash v4+, you can try this:

Code:

shopt -s globstar
for dir in . **/ ; do        # Use . to include the top level too.
        fuser "$dir"
done

** is the new globstar globbing pattern, which matches recursively. You have to enable it first. Adding a / after it makes it match only directories. You can tack on additional globs onto it to search for files inside a directory tree (e.g. **/*.txt to grab all text files). You can also enable shopt -s dotglob to match hidden files.

find may sometimes still be more efficient however.

vikas027 12-28-2011 06:03 AM

Quote:

Originally Posted by thllgo (Post 3560815)
that worked, thanks.

Hi,

Please mark this thread as solved. This is VERY useful for others.


All times are GMT -5. The time now is 06:46 PM.