Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.
grep -r xxx" /*
grep: /dev/log: No such device or address
grep: /dev/dvd: No medium found
grep: /dev/cdrw: No medium found
grep: /dev/cdrom: No medium found

but it takes more then 2 hours without results. If I use grep -r "xxx" /etc then I get results. How can I search in whole disk?

share|improve this question

migrated from stackoverflow.com Jul 11 '12 at 21:24

This question came from our site for professional and enthusiast programmers.

2  
/* is the path to every file on the system. How about just replacing /* with /. / is a directory as much as /etc. –  Linuxios Jul 11 '12 at 20:55
add comment

2 Answers 2

Using grep -r blindly on / is not a good idea. Several directories (e.g. /dev and /proc) contain special files that should not be accessed in an uncontrolled manner - doing so could just flood your screen with errors, have you wait until the end of the world or even crash your system.

You need to use find to prevent the search from descending into those directories and leave special files alone:

  • Use explicit negated -path options:

    find / -maxdepth 2 -type f ! -path '/proc/*' ! -path '/dev/*' -exec grep "xxx" {} +
    
  • Use the -prune option:

    find / -maxdepth 2 -path '/proc' -prune -o -path '/dev' -prune -o -type f -exec grep "xxx" {} +
    
  • Use the -xdev option to avoid descending to other filesystems completely:

    find / -maxdepth 2 -xdev -type f -exec grep "xxx" {} +
    

-type f will only let through regular files. You can use as many -path and/or -prune options as you need to fine-tune the output of find.

Also note the use of the -exec ... + variation of -exec that calls grep with multiple files, rather than launch a separate grep process for every single one of them. Alternatively, you could use xargs to call grep:

find / -maxdepth 2 -xdev -type f -print0 | xargs -r -0 grep "xxx"

Here is an older answer of mine to a related question...

share|improve this answer
add comment

If you want to search the whole disk, use find

find / -type f -exec grep "xxx" {} /dev/null \;

The /dev/null in the answer allows grep to print the file name with the match.

In order to avoid running a new grep process for each file, I wrote a Perl version of grep (pgrep) which reads file names from stdin. You would run it like

find / -type f -print | pgrep "string to find"

The code is here:

#!/bin/perl

$pat = shift || die "I won't search for nothing";
while (<STDIN>) {
    chomp;
    if(-f $_ && open(IN, $_)) {
        @matches = grep(/$pat/, <IN>);
        close IN;
        for $match (@matches) {
           print $_, ": ", $match;
        }
    }
}
share|improve this answer
    
1. find ... -exec ... ; is a very bad idea; it will launch a new grep process for each matching file. 2. The reason grep ... /dev/null prints out the file name is because you force grep into multi-file mode by adding /dev/null as a second file. grep -H is the proper way to do this... –  thkala Jul 11 '12 at 21:14
    
@thkala grep -H is not the proper way. the -H switch is a non-standard GNU extension see HP-UX and AIX –  dadinck Jul 13 '12 at 15:37
    
If you are doing this as a one time command, make sure to "nice" it. If you will be doing this often, generate a proper script with "find2perl" –  dadinck Jul 13 '12 at 15:41
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.