Reputation: 10817
The following code saves my_string
in the file my_filename
and
then checks whether pattern1
and pattern2
are in the file. The
first is; the second isn't.
#!/bin/bash
my_string="One two three four"
pattern1="two three"
pattern2="two four"
my_filename="my_temp_file"
safeGrepCommand() {
typeset command_to_run="$*"
typeset ret_code
# echo command_to_run=$command_to_run
eval $command_to_run
ret_code=$?
if [ $ret_code != 0 ]; then
printf "Pattern %s is not in the file %s.\n" "${my_pattern}" "${my_filename}"
exit $ret_code
fi
}
echo $my_string > $my_filename
grep_command1="grep --quiet ${pattern1} ${my_filename}"
safeGrepCommand "$grep_command1"
grep_command2="grep --quiet ${pattern2} ${my_filename}"
safeGrepCommand "$grep_command2"
rm -f $my_filename
I am expecting to see the output
Pattern two four is not in the file my_temp_file.
Instead I see
grep: three: No such file or directory
grep: four: No such file or directory
As you'll see if you uncomment the echo line inside the function, the problem is that the quotation marks are not seen by grep.
command_to_run=grep --quiet two three my_temp_file
command_to_run=grep --quiet two four my_temp_file
How do I get bash to pass the quotation marks to grep? Alternatively, how do I specify "two three" as a regexp with [:space] and not worry about quotation marks.
Upvotes: 0
Views: 85
Reputation: 241701
Here's one way of resending arguments in a shell function:
doit_or_complain() {
# The arguments are captured only to show how to do it. In practice,
# I would just use "${@}" to run the command.
local -a command=("$@")
"${command[@]}"
local rc=$?
if ((rc)); then
echo "The command failed" >> /dev/stderr
fi
return $rc
}
That will work with any random arguments:
doit_or_complain grep "a b" "./my file with spaces in its name"
If you want to pass a complicated command to the shell function, you should use an array:
theCommand=(grep "a b" "./my file with spaces in its name")
#...
doit_or_complain "${theCommand[@]}"
Note: The function in the OP used exit $rc
if the command failed. That will exit the current shell, not just the function, which might be considered a tad unexpected, if not unsafe.
Upvotes: 1
Reputation: 26667
Wrap the pattern variable in double quotes as
grep_command1="grep --quiet \"${pattern1}\" \"${my_filename}\""
safeGrepCommand "$grep_command1"
grep_command2="grep --quiet \"${pattern2}\" \"${my_filename}\""
safeGrepCommand "$grep_command2"
Upvotes: 0