How to raise and take care of shell scripts: True and False

What is true, what is false?

I already wrote about the exit code of programs in the Errors chapter. The conclusion (0 = o.k., not equal to 0 = error) is also valid when you evaluate expressions: 0 = true, not equal to 0 = false. The shell builtin test works exactly this way: It returns 0, if the tested expression is true, 1 otherwise. Try it:

  jan@jack:~/tmp> test 1 -eq 1
  jan@jack:~/tmp> echo $?
  0
  jan@jack:~/tmp> test 1 -eq 2
  jan@jack:~/tmp> echo $?
  1

So it's without problems possible to use the exit code of programs directly for example in "if-then-else" tests or as exit conditions in loops. Such control structures also evaluate, whether their argument is zero or not. Often one looks at constructs, which are unnecessary complicated and could be written much simplier:

  # check if a file contains a defined search pattern
  # ugly
  if test `grep pattern file | wc -l` -gt 0; then
    ...
  fi
  # simple
  if grep -q pattern file; then
    ...
  fi

  # loop as long as there exist -bak files
  # ugly
  while true; do
    num_bak_files=`ls *.bak 2>/dev/null | wc -l`
    test $num_bak_files -eq 0 && break
    ...
  done
  # simple
  while ls *.bak >/dev/null 2>>&1; do
    ...
  done

By the way: The true used within the while loop is a shell builtin, which always returns 0, it's counterpart is - exactly - false.

Last but not least: In my examples I sometimes used constructs like :
command1 && command2 or
command1 || command2
To tell the truth these are simply AND resp. OR conditions. They use the fact, that the shell is as lazy as most programmers:

As a result, one has to be careful using the result of one of these constructs: It's not clear in all cases. Only if the result of an AND condition is true, you can assume that both commands succeeded. If the result is false, you don't know, which of the commands failed. For the OR condition it's exactly the other way: Only when it's result is false you know, that both commands failed. If the result is true, you can't find out, which command succeeded or if both of them did return true.