I'm trying to build a command that pipes the results of one grep command to another grep command in a bash function. Ultimately, I want the command executed to look like this:
grep -I -r FooBar /code/internal/dev/ /code/public/dev/ | grep .c:\|.h:
The function I'm writing stores the first part of the command in a string, then appends the second part:
grep_cmd="grep -I -r $pattern $@"
if (( ${#file_types[@]} > 0 )); then
file_types="${file_types[@]}"
file_types=.${file_types// /':\|.'}:
grep_cmd="$grep_cmd | grep $file_types"
fi
echo "$grep_cmd"
${grep_cmd}
This throws an error after the output from the first part:
grep: |: No such file or directory
grep: grep: No such file or directory
grep: .c:\|.h:: No such file or directory
Changing the last line from ${grep_cmd} to just "$grep_cmd" displays no output from the first part and throws a different error:
bash: grep -I -r FooBar /code/internal/dev/ /code/public/dev/ | grep .c:\|.h:: No such file or directory
Per this SO answerthis SO answer, I tried changing the last line to $(grep_cmd). This throws another error:
bash: grep_cmd: command not found
This SO answerThis SO answer suggests using eval $grep_cmd. This suppresses the errors but also suppresses the output.
This oneThis one suggests using eval ${grep_cmd}. This has the same results (suppresses the errors and output). I tried enabling debugging in bash (with set -x), which gives me this:
+ eval grep -I -r FooBar /code/internal/dev/ /code/public/dev/ '|' grep '.c:\|.h:'
++ grep -I -r FooBar /code/internal/dev/ /code/public/dev/
++ grep '.c:|.h:'
It looks like the pipe is being escaped, so the shell interprets the command as two commands. How do I properly escape the pipe character so it interprets it as one command?