I am attempting to write a bash script that searches contents of files in a specified directory tree for the presence of a specified substring.
Using grep's recursive function alone is not sufficient, since I potentially need to iterate over the / directory (and all sub-directories) of a system, which makes grep run out of memory and abort. Therefore I decided to get a list of all directories and sub-directories in the specified directory tree using find with the following variables denoting arguments passed to the script.
searchdir=$HOME # passed in a script argument
searchstr="secret" # passed in a script argument
I call the find utility and store the output into a temporary file.
TF=$(mktemp)
find ${searchdir} -type d 1>$TF 2>/dev/null
With the list of all directories in the temporary file, I proceed to iterate over the lines of this file using a while-do loop with the intention to perform a search over all files in each directory. For grep, I use the format of parameters provided in this answer to search all files, including the hidden ones, in the single directory.
cat $TF | while read line || [[ -n $line ]];
do
grepdir="${line}/{*,.*}"
grep -sHn "${searchstr}" ${grepdir}
done
... however, that code produces no output.
I verified that...
The ${TF} does contain the correct list of all directories. Outputting the ${grepdir} variable gives the output I'm expecting to find.
/home/user/{*,.*}
/home/user/.ssh/{*,.*}
/home/user/test/{*,.*}
# ... and so on
If I run the grep command with a hardcoded directory, particularly the ~/test/ directory, which contains two test files with the string it's supposed to find
grep -sHn "${searchstr}" /home/user/test/{*,.*}
... it correctly outputs the two files containing the substring "secret".
/home/user/test/asdf:7:secret
/home/user/test/test.txt:5:asdfasfdsecretaasdfafd
A format that works for me is the one originally mentioned in the answer discussing the recursive use of grep. If I do this:
cat $TF | while read line || [[ -n $line ]];
do
grep -rn "${line}" -e "${searchstr}"
done
... I get some output (technically correct, but with many duplicate entries), but since the grep is processing the directories recursively and I have a list of all directories, I am bound to get the same results many times and on directories such as the aforementioned root directory, grep will fail entirely, which is what I'm trying to avoid.
I should also probably mention that my desperate hacks to get it working, such as passing $(echo "${grepdir}") as the parameter, led to no results as well.
There is most likely a misconception in my thinking or understanding of bash. Shouldn't bash expand the ${grepdir} variable before making a call to grep? Where is my script going wrong?
-sfrom yourgrepcommand, I suspect you will see a bunch of error messages like/home/user/{*,.*}: No such file or directory- is that the case? – steeldriver Nov 25 '19 at 18:36