Operator && executes the next command the if previous command had a successful execution, (returned exit code ($?) 0 = logical true).
In form A && B || C
, command (or condition) A is evaluated and if A returns true (success, exit code 0) then command B is executed.
If A fails (thus will return false - exit code other than 0) and/or B fails (returning false) then command C will be executed.
Also &&
operator is used as an AND in condition checks and operator ||
works like OR in condition checks.
Depending on what you want to do with your script, form A && B || C
can be used for condition checks like your example or can be used to chain commands and ensure a series of commands to be executed if previous commands had a successful exit code 0.
This is why it is common to see commands like:
do_something && do_something_else_that_depended_on_something
.
Examples:
apt-get update && apt-get upgrade
If update fails then upgrade is not executed, (makes sense in the real world...).
mkdir test && echo "Something" > test/file
The part echo "Something"
will be executed only if mkdir test
was successful and operation returned exit code 0.
./configure --prefix=/usr && make && sudo make install
Usually found on compiling jobs to chain necessary dependent commands together.
If you try to implement above "chains" with if-then-else you will need much more commands and checks (and thus more code to write - more things to go wrong) for a simple task.
Also, keep in mind that chained commands with && and || are read by shell left to right. You might need to group commands and condition checks with brackets to depend the next step on the successful output of some previous commands .
For example see this:
root@debian:$ true || true && false;echo $?
1
#read from left to right
#true OR true=true AND false = false = exit code 1=not success
root@debian:$ true || (true && false);echo $?
0
# true OR (true AND false)=true OR false = true = exit code 0 = success
Or a real life example:
root@debian:$ a=1;b=1;c=1;[[ $a -eq 1 ]] || [[ $b -eq 1 ]] && [[ $c -eq 2 ]];echo $?
1
#condition $a = true OR condition b = true AND condition $c = false
#=> yields false as read from left to right, thus exit code=1 = not ok
root@debian:$ a=1;b=1;c=1;[[ $a -eq 1 ]] || [[ $b -eq 1 && $c -eq 2 ]];echo $?
0
#vars b and c are checked in a group which returns false,
#condition check of var a returns true, thus true OR false yields true = exit code 0
Keep in mind that some commands return different exit codes depending on the process executed, or return different codes depending on their actions, (for example command GNU diff
, returns 1 if two files differ, and 0 if they don't). Such commands need to be treated with care in && and ||.
Also just to have all the puzzle together, mind the concatenation of commands using ;
operator . With a format A;B;C
all commands will be executed in series no matter what was the exit code of command A
and B
.