I am confused:
echo "i-am-sure-this-is-here" > /tmp/myfile
if [[ $(grep -q sure /tmp/myfile) ]] ; then echo "Found!" ; else echo "wtf! not found" ; fi
Which gives:
wtf! not found
So I try something even simpler:
if [[ true ]] ; then echo "true -> expected" ; else echo "true -> unexpected" ; fi
if [[ false ]] ; then echo "false -> unexpected" ; else echo "false -> expected" ; fi
Which gives me something unexpected:
true -> expected
false -> unexpected
I am clearly not understanding this. Some questions:
- Why is
false
true? - Is the conditional evaluating the exit code of the command at all? I expected
0
exit code to meantrue
(the return code if thetrue
command), and any non0
exit code to meanfalse
(thefalse
command returns1
)
How to evaluate exit codes of commands in an if-else-fi
construct in bash
without having to revert to explicitly comparing the exit code ($?
) to an expected value, which is ugly and not very readable?
I know this would work:
grep -q sure /tmp/myfile
if [[ $? -eq 0 ]] ; then echo "Found!" ; else echo "wtf! not found" ; fi
But this is longer (2 lines instead of 1), and uglier.
CodePudding user response:
if
tests the status code of its "argument". Therefore
if grep -q sure /tmp/myfile
then
echo found
fi
would do the job.
CodePudding user response:
Please read about [[
compound command. Grep with option -q output nothing:
$ grep --help
...
-q, --quiet, --silent suppress all normal output
...
That is why the first check is failing.
The second check is true for both the tries because this is how [[ ]]
works true|false doesn't matter you can write down whatever you want here it always be true. Only the empty string will fail.
$ [[ yes ]] && echo ok || echo fail
ok
$ [[ no ]] && echo ok || echo fail
ok
$ [[ fail ]] && echo ok || echo fail
ok
$ [[ '' ]] && echo ok || echo fail
fail
But you don't actually need to use test
or [[]]|[]
to check grep. Use its exit codes:
grep -q sure /tmp/myfile && echo ok || echo fail
ok