0

I am searching for a file in the directory tree below me. When I try find . -name xyz, I get screenfuls of find: '/home/fred' : Permission denied

That makes sense as I don't have access rights to those directories. So I try

find . -name xyz | grep -v Permission 

which should remove the lines I don't want. Well, I exactly the same screenfuls as before. The grep doesn't do anything

What's going on and how do I fix it?

6

"Permission denied" is a warning and not the kind data you'd expect from find. In order to keep error messages separate from the requested user data, find prints the filenames to its standard output channel 1 and the warning to the standard error channel 2. This behaviour is very common among many unix command-line tools. The shell typically displays both channels. You can avoid it by explicitly re-directing the error stream somewhere else, e.g. the void represented by /dev/null:

find . -name xyz 2>/dev/null
| improve this answer | |
  • The shell has the habit of displaying both channels. This sounds a bit like a weakness. Actually one would even want channel "error" 2 in red i.e. "on top of" normal output. If the shell has a habit, it is letting you choose between default "split but displayed together", or suppress like you show, or merge like I show, or log with 2>errorfile. (just a side note on that word -- good answer) – user373503 Jan 27 at 5:57
  • @rastafile Good point. I adjusted the wording. – Hermann Jan 27 at 8:29
4

Your issue is that you're trying to filter out (remove) the error messages from the standard output of find. Error messages (and general diagnostic messages, as well as interactive prompts) are displayed on the standard error stream, which can't be piped. You therefore can't get rid of the error messages using grep (without merging the standard error stream into the standard output stream).

Using GNU find (which implements the nonstandard -readable test):

find . -type d ! -readable -prune -o -name xyz -print

This would look for anything called xyz in or below the current directory and print out the found pathnames. Whenever find encounters a directory that the current user does not have access to read, this directory is removed from the search tree (the search tree is pruned with -prune).

This gets rid of the "permission denied" errors originating from trying to access directories that you can't access. It does this by simply not getting into situations where these errors would be generated.

By avoiding grep, this will also avoid accidentally filtering out files found in directories called, literally, Permission. It also allows you to see any other errors that may be generated while searching for xyz (whatever these errors might be), or to write in-line scripts, executed through find ... -exec ... that may want to use the error stream, or to use find ... -ok ... for asking the user for confirmation before performing some action.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.