1

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.

Narek
  • 245
  • 1
  • 4
  • 15

4 Answers4

10

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.

geekosaur
  • 7,175
  • 1
  • 20
  • 19
3

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.

Dan Berindei
  • 130
  • 4
  • 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 02:31
1

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.

rvs
  • 4,125
  • 1
  • 27
  • 31
0

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.

Phil Hollenback
  • 14,947
  • 4
  • 35
  • 52
  • " 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