Here is a command that works perfectly for me on the command-line:
find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;
When I run the above command substituting the search path .
with any path, the command still shows me only the list of files with .c
or .h
extension.
Now, I want to write a simple bash script with the same command as the value of a variable, just so that I could execute the script with minor modifications to do a similar search, rather than having to type the command all over again. But that is where I run into the escape rules nightmare (or lack of proper understanding of it!).
I wrote a script as shown below:
#!/bin/bash
path="/home/vinod"
string="somestring"
command="find ${path} -type f -exec grep -Hin --include=.h --include=.c '${string}' {} ;"
echo $command
$command
When I run the above script, I get the command echoed two times instead of once, as shown below
find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;
find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;
and the following run-time error:
find: missing argument to -exec
As you can see from the echo, the command is exactly the same as when I ran it on the command-line, for which I got the expected result.
Any thoughts on what could be wrong with my script?
TIA
find …
command in the script. And quote. And use the right quotes. – Kamil Maciorowski Jul 13 '23 at 06:46\;
is unescaped by the variable expansion, and;
is taken by shell as end of command. Also note the*.c
and*.h
should be single-quoted. Yes, the text is passed on, but the shell first attempts an expansion of every file in your directory before it finds it cannot return anything from it. – Paul_Pedant Jul 13 '23 at 09:56find
command fails is that variables contain data, not code, and their expansions are not parsed for shell syntax (like quotes or backslashes). – ilkkachu Jul 13 '23 at 12:41