Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

When I call

cd /
grep -r "some_str" .

then I see lots of files printed on the screen and in the end of the line I see ": Permission denied". How I can tell the bash to search only in file that I have permission. This will be obviously faster then the standard grep.

share|improve this question
    
I have to mention there's always the completely stupid blunt-force way to do it, which is to run grep through sudo. –  Phil Hollenback Mar 18 '11 at 8:54
add comment

4 Answers 4

Use find / -readable -print0 | xargs -0 grep -H "some_str" instead of grep -r. (Requires GNU find, but grep -r is GNUish so I suspect that's not a problem.)

But in fact it's not so "obvious" that it's faster; grep -r lets the open() call find out you can't read it, whereas the find version has to stat() first, then grep does the open() — and the most expensive part of this, for files that aren't readable, is the kernel converting pathnames to filesystem index nodes. (Actually searching readable files will be the bulk of execution time otherwise, for files of any significant size.) Quite likely the faster approach is just to append 2>/dev/null to the grep -r so there isn't any time lost printing error messages to slow terminals.

share|improve this answer
    
Thanks, I didn't know about this switch. Very useful. –  rvs Mar 18 '11 at 8:30
    
ha yeah that's what I do too - just throw away the grep stderr. –  Phil Hollenback Mar 18 '11 at 8:52
add comment

You could use grep -s to ignore messages about unreadable files.

Printing the error messages is the only thing that could cause a slowdown, it's not like grep reads the whole file and at then drops all the results because it didn't actually have the rights to read it.

share|improve this answer
    
This is a better answer than throwing away all errors via stderr redirection, because you're only throwing away the errors you specifically don't care about. -s is also a POSIX feature, so "should" be fairly portable. –  Daniel Lawson Mar 19 '11 at 2:31
add comment

You may try find:

find / -perm o=r -or -user <user> -exec grep whatever '{}' \;

Howewer, this command won't search in files, to which you have permission via group.

UPDATE: there is find -readable, as suggested by another answer.

share|improve this answer
add comment

Here's a fun way to do it with GNU Parallel, assuming that your find(1) doesn't support the -readable flag:

find / -type f 2>/dev/null | parallel -m "grep blah {}"

The -m option to parallel makes it stuff as many files as possible into each call to grep, which is more efficient that just grepping one file at a time.

I realize a problem with this is it will throw away other find errors besides permissions problems. I suspect there may be a way to work around this with the find option -depth but I haven't explored that yet.

It would be interesting to benchmark the find / grep vs. grep -r vs. parallel approaches on a multicore system and see which is faster.

share|improve this answer
    
" and {} are not needed in the first example. Usually the bottleneck is not the CPU power but disk seeks. So the benchmark would most likely depend more on what kind of disk you have (SSD would be fast, where as a single magnetic disk would be slow). –  Ole Tange Mar 18 '11 at 23:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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