0

I am trying to find all the files in a directory structure which contain a specific word, but it is not working correctly.

  • For example: when run from the path /Institute/IITDhanbad/, the command
    grep -rn "Programmer" *
    
    giving result as
    BTECH/CompScience.txt:22:    Sudip is a Programmer
    
  • However, when run from the path /Institute/IITDhanbad/MTECH, the same command gives
    CSP/Boys/Good/Electronics.txt:13:    Sourav is a Programmer
    

The problem is, that the expected result when running the grep call in /Institute/IITDhanbad/ folder was to have both results, i.e.

BTECH/CompScience.txt:22:               Sudip is a Programmer
MTECH/CSP/Boys/Good/Electronics.txt:13: Sourav is a Programmer

What is going wrong and how to resolve this?

Some additional info:

  • The file type and access permissions are:

    File Mode
    MTECH drwxrwsr-x
    BTECH drwxrwsr-x
    CSP lrwxrwxrwx
  • ls -ld in /Institute/IITDhanbad/ path:

    drwxrwsr-x 4 suresh faculty 4096 Sep 16 00:53
    
  • ls -ld in /Institute/IITDhanbad/MTECH path:

    drwxrwsr-x 4 suresh faculty 4096 Sep 16 00:53
    
  • ls -ld in /Institute/IITDhanbad/MTECH/CSP path:

    dr-xr-sr-t 4 ganesh faculty 4096 Sep 12 20:58 .
    
0

3 Answers 3

3

CSP is a symlink (see l in lrwxrwxrwx). Apparently your grep does not follow symlinks with -r, except symlinks provided as arguments. When you do:

grep -rn "Programmer" *

in the parent directory of CSP (i.e. in /Institute/IITDhanbad/MTECH/, right?), CSP appears as an argument after the shell expands *. But if you do this one directory "higher" (in /Institute/IITDhanbad/) then CSP is not an argument, it's a symlink encountered by grep during its recursive scanning.

GNU grep works this way. Is your grep GNU grep? If so, see the manual for -R. -R is like -r but it does follow symlinks.

Note if you did grep -rn "Programmer" . in the parent directory of CSP then CSP would not appear as an argument. The usage of * was crucial for what you observed.

0
1

Answer

GNU grep manual states that the option -r only follows the immediate symlinks (the ones given on the command line), but not the ones further away inside the directory hierarchy:

-r
--recursive
For each directory operand, read and process all files in that directory, recursively. Follow symbolic links on the command line, but skip symlinks that are encountered recursively. Note that if no file operand is given, grep searches the working directory. This is the same as the ‘--directories=recurse’ option

So, the directory CSP, being a symlink inside the immediately given directory MTECH, doesn't get traversed when searching for the given text.

NB: Previous answer, prior to the clarification of the question:

Possible cause of the problem

The subdirectory MTECH could not have execute permission bit set. For example:

$ mkdir -p one/two
$ cd one
$ cat <<EOT > test.txt
abc def
EOT
$ cp test.txt two
$ grep -rn def *
test.txt:1:abc def
two/test.txt:1:abc def
$ chmod -x two
$ grep -rn def *
test.txt:1:abc def
grep: two/test.txt: Permission denied

Admittedly, this would give an error message on stderr. However, if grep is set up as an alias to /usr/bin/grep -s:

$ alias grep='/usr/bin/grep -s'
$ grep -rn def *
test.txt:1:abc def

Which is the possible final piece of the puzzle.

Solution

Use unalias grep before running grep, or use /usr/bin/grep instead of just grep.

2
  • Do you think they changed the permissions of the directory between those commands? Since without the x bit on the directory, they can't change to the directory to run the other grep either.
    – ilkkachu
    Sep 23, 2021 at 22:47
  • @ilkkachu Possibly, with the one in the subdirectory being done first, followed by the chmod -x and then the grep in parent directory. Sep 23, 2021 at 23:02
-1

You can simplify your approach by simply executing your cmd as:

target_dir="/path/to/directory/of/interest"
[ -d "$target_dir"  ] && grep -rn -e "Programmer" "$target_dir"

or similarly to what you tried but including the test on the file operand being a directory:

target_dir="/path/to/directory/of/interest"
[ -d "$target_dir"  ] && cd "$target_dir" && grep -rn -e "Programmer"

using the fact that recursing (-r) with no file operand provided is the same as recursing from $PWD down.

Is this what you were asking for ?

1
  • I am asking why all the results are not displayed in '/Institute/IITDhanbad/' folder when I am using grep?
    – Suresh
    Sep 24, 2021 at 3:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .