I am trying to automate our application backup. Part of the process is to check the exit status of egrep
in an if
statement:
if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
[ egrep -i -q "error|warning|fatal|missing|critical" "$File" ]
then
echo "testing"
fi
I expected it to output testing
because the file exists and egrep
returns success, but instead I'm getting an error:
-bash: [: too many arguments
I tried with all kinds of syntax - additional brackets, quotes etc but error still persists.
Please help me in understanding where I am going wrong.
You are making the common mistake of assuming that [
is part of the if
statement's syntax. It is not; the syntax of if
is simply
if command; then
: # ... things which should happen if command's result code was 0
else
: # ... things which should happen otherwise
fi
One of the common command
s we use is [
which is an alias for the command test
. It is a simple command for comparing strings, numbers, and files. It accepts a fairly narrow combination of arguments, and tends to generate confusing and misleading error messages if you don't pass it the expected arguments. (Or rather, the error messages are adequate and helpful once you get used to it, but they are easily misunderstood if you're not used.)
Here, you want to check the result of the command egrep
:
if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
egrep -i -q "error|warning|fatal|missing|critical" "$File"
then
echo "testing"
fi
In the general case, command
can be a pipeline or a list of commands; then, the exit code from the final command is the status which if
will examine, similarly to how the last command in a script decides the exit status from the script.
These compound commands can be arbitrarily complex, like
if read thing
case $thing in
'' | 'quit') false;;
*) true;;
esac
then ...
but in practice, you rarely see more than a single command in the if
statement (though it's not unheard of; your compound statement with ||
is a good example!)
Just to spell this out,
if [ egrep foo bar ]
is running [
aka test
on the arguments egrep foo bar
. But [
without options only accepts a single argument, and then checks whether or not that argument is the empty string. (egrep
is clearly not an empty string. Quoting here is optional, but would perhaps make it easier to see:
if [ "egrep" ]; then
echo "yes, 'egrep' is not equal to ''"
fi
This is obviously silly in isolation, but should hopefully work as an illustrative example.)
The historical reasons for test
as a general kitchen sink of stuff the authors didn't want to make part of the syntax of if
is one of the less attractive designs of the original Bourne shell. Bash and zsh
offer alternatives which are less unwieldy (like the [[
double brackets in bash), and of course, POSIX test
is a lot more well-tempered than the original creation from Bell Labs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With