============================================== Return Code, Exit Status, ||, &&, test, and if ============================================== -IAN! idallen@idallen.ca >Why do we use " || ", for examples: > test -f /etc/passwd || echo hello >I tried using " | ", only this one works fine. The token "||" is not at all related to the token "|", just as in C language "&&" is not related to "&", "||" is not related to "|", and "==" is not related to "=". They mean different things. In the file script_style.txt you'll find a section titled "Testing Return Codes of Commands" that explains briefly how "||" works to test the return codes of commands in shell scripts. Here are some more examples. Here is how the return code (exit status) is set by the Unix "test" command, for a file that exists and one that does not exist: $ test -f /etc/passwd <== set the return code $ echo $? <== display it 0 $ test -f /nosuchfile <== set the return code $ echo $? <== display it 1 Here's how to use the "||" token to have the shell conditionally execute the command to the right if the command on the left returns a bad (non-zero) exit status: $ test -f /etc/passwd || echo "return code $? - no such file" $ (Above: good return status, do *NOT* execute command after "||") $ test -f /nosuchfile || echo "return code $? - no such file" return code 1 - no such file $ (Above: bad return status, do execute command after "||") $ test -f /bin || echo "return code $? - no such file" return code 1 - no such file $ (Above: bad return status [not a file], do execute command after "||") The "||" operator provides a quick way to test the return code of the command on the left, without using a full shell "if" statement. To see the difference, compare the following two identical tests: test -f /nosuchfile || echo "return code $? - no such file" if ! test -f /nosuchfile ; then echo "inaccessible or not a file" fi One test takes one line to program; the other takes three. Other than that, the output is identical. We use "||" because it's easy and short. The "&&" token works the opposite way to "||". The command on the right is executed only if the command on the left returns a good (zero) exit status: $ test -f /etc/passwd && echo "good status" good status $ (Above: good return status, do execute command after "&&") $ test -f /nosuchfile && echo "good status" $ (Above: bad return status, do *NOT* execute command after "&&") $ test -f /bin && echo "good status" $ (Above: bad return status, do *NOT* execute command after "&&") The "&&" operator also provides a quick way to test the return code of the command on the left, without using a full shell "if" statement. Here are two identical tests, comparing "if" and "&&": test -f /etc/passwd && echo "file exists" if test -f /etc/passwd ; then echo "file exists" fi One test takes one line to program; the other takes three. Other than that, the output is identical. We use "&&" because it's easy and short. The most common use of "||" is as a "quick exit" if an important command in a shell script fails. In the script fragment below, if the copy doesn't work, there is no point in continuing with the rest of the script: cp "$1" foo || exit $? <== exit immediately if cp fails chmod 700 foo wc foo >foo.count || exit $? <== exit immediately if wc fails chmod 755 foo.count We add "|| exit $?" to the ends of critical lines in the script. If the command on the left fails, there is no point in continuing with the rest of the script. We could write the same fragment using shell "if" statements; but, the code is three times longer for each test: if ! cp "$1" foo ; then exit 1 fi chmod 700 foo if ! wc foo >foo.count ; then exit 1 fi chmod 755 foo.count The above code is identical to the code that uses "||"; but, it's longer. In the file script_style.txt you'll find a section titled "Testing Return Codes of Commands" that has examples of using "||" to test the return codes of important commands in shell scripts.