Home > Blockchain >  Confused about bash conditionals [duplicate]
Confused about bash conditionals [duplicate]

Time:09-21

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:

  1. Why is false true?
  2. Is the conditional evaluating the exit code of the command at all? I expected 0 exit code to mean true (the return code if the true command), and any non 0 exit code to mean false (the false command returns 1)

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
  • Related