3

I want to tell grep, on Debian, not to search through files in /proc or /sys. But if I use:

 --exclude-dir=/proc

or

--exclude-dir={/proc,/sys}

or

--exclude-dir=/proc --exclude-dir=/sys

Then grep still read /sys and crashes because of that. So how can I tell grep to skip the /proc and /sys directories?

wxi
  • 149
  • 2
  • 10

3 Answers3

9

The documentatiton for --exclude-dir in the GNU grep manual says

--exclude-dir=GLOB

Skip any command-line directory with a name suffix that matches the pattern GLOB. When searching recursively, skip any subdirectory whose base name matches GLOB. Ignore any redundant trailing slashes in GLOB.

As you can see, the given pattern (GLOB) will be applied only to the actual filename of the directory, and since a directory name can't contain / in its name, a pattern like /proc will never match.

Therefore, you would have to use --exclude-dir=proc and --exclude-dir=sys (or --exclude-dir={proc,sys} if you are short on time), and at the same time be aware that this would skip not only /proc and /sys but also any other directory with either of those names.

Another way of recursively searching a complete directory tree from the root down while avoiding these two directories is by using grep from find:

find / \( -type d \( -path /proc -o -path /sys \) -prune \) -o \
    -type f -exec grep 'PATTERN' {} +

This would detect the two specific directories /proc and /sys and stop find from descending into them. It would also feed any found regular file to grep in as large batches as possible at a time.

Kusalananda
  • 333,661
  • why do you use -prune? – Shuzheng Nov 04 '20 at 09:29
  • @Shuzheng To stop find from entering those directories. – Kusalananda Nov 04 '20 at 10:41
  • ♦ - Will you elaborate? What directories specifically? – Shuzheng Nov 06 '20 at 07:40
  • @Shuzheng /proc and /sys. These are the directories that the user in the question wants to avoid. – Kusalananda Nov 06 '20 at 07:41
  • Couldn't this be written using negation instead? ! \( -path /proc -o -path /sys \)? – Shuzheng Nov 06 '20 at 13:20
  • @Shuzheng That would stop grep from being executed with files from those directories, yes, but it would not have stopped find from trying to access everything inside /sys and /proc. The -prune predicate "prunes" (removes) a directory tree from the search tree. – Kusalananda Nov 06 '20 at 13:23
  • Ahh, I see! So, exactly does -prune know which directories to apply to? Is it always the directories on the left side of the invisible -a (AND)? – Shuzheng Nov 06 '20 at 13:29
  • @Shuzheng You typically use -prune to stop find from even considering the files and directories beneath a path. In this case, we don't want to pass e.g. /proc/uptime or /proc/version or any of the other thousands of pathnames under /proc. It is more efficient to ignore /proc than to test each and every name under /proc against some pattern. – Kusalananda Nov 06 '20 at 13:29
  • @Shuzheng -prune is an "action". It acts on the current pathname, just like -print does. – Kusalananda Nov 06 '20 at 13:30
  • +1 for this quote "the given pattern (GLOB) will be applied only to the actual filename of the directory, and since a directory name can't contain / in its name, a pattern like /proc will never match." ... That answers my question that drew me here: why isn't it excluding a sub-path like 'configs/users'. – TonyG Jun 29 '22 at 18:57
1

However, this works well!

 --exclude-dir={proc,sys} 
terdon
  • 242,166
wxi
  • 149
  • 2
  • 10
  • 2
    Sorry! I misunderstood completely and thought your question was "why does --exclude-dir=/proc and --exclude-dir=/proc --exclude-dir=/sys not work. So an answer would explain why those fail, not give a command that works. If you are instead asking "how can I do this", then this is indeed an answer and I was wrong to delete it. If this is the case, could you please also edit your question so what you are asking is clearer? – terdon Jan 10 '19 at 21:47
  • Someone has already done it, but thanks for your kindness ! – wxi Jan 11 '19 at 09:37
  • Hmmm.... I would be interested in knowing what the difference between proc and /proc would be and why using /proc does not exclude the /proc directory. It seems to me that using proc would make grep also exclude directories with this name in other parts of the directory structure. – Kusalananda Jan 11 '19 at 09:47
  • I read in first time in a other place that it take /proc but ./proc too. And i read here that because i have precised "/" in the location of search, grep does need to read proc and not /proc, because it's relative to where he begin to search – wxi Jan 11 '19 at 13:47
  • @Kusalananda maybe because --exclude-dir's pattern should match the name, not the path of the directory? –  Jan 11 '19 at 23:40
  • @mosvy I know. I discuss this in my answer as it's missing from this one. – Kusalananda Jan 11 '19 at 23:41
  • @Kusalananda sorry, I have missed your answer. –  Jan 11 '19 at 23:58
-1

You must know that grep will take the selected directory as the base for the file names on the search, because that on the search list they will be showed as dev/, sys/ etc. so instead of using:

grep 'yourstring' -R --exclude-dir={/dev,/sys,/proc} / 

You must use:

grep 'yourstring '-R --exclude-dir={dev/,sys/,proc/} /
  • That's what i said but a moderator has deleted my answer. So we can't answer ourselves here. "But --exclude-dir={proc,sys} works well !" – wxi Jan 10 '19 at 18:06