Reputation: 282875
I'm using Bash
specifically, but I imagine most shells behave the same way.
I often do
hg pull && hg update --clean
But it just occurred to me, if hg pull
returns 0
on success, why does it execute the hg up
command?
Typically the way the &&
operator works is that it will only execute the next argument if the previous one was truthy. Is 0
truthy in Bash, or what?
This came up because I tried doing the equivalent in Python, but I had to write it like this:
call(['hg','pull']) or call(['hg','update','--clean'])
Upvotes: 2
Views: 867
Reputation: 63902
As help, you can remember than command when end correctly (without errors) mean true. And his exit codes are zero
so,
therefore, for example, the correct way deleting all files recursively is
$ pwd
/
$ cd /tnp && rm -rf *
cd: can't change directory #and the rm WILL NOT executed
and not
$ pwd
/
$ cd /tnp ; rm -rf *
cd: can't change directory #but the rm IS executed (in the root directory)
Added:
command1 && command2 && command3
^ ^
| +-- run, only when command2 exited OK (zero)
|
+--run only when command1 exited OK (zero)
So, command3 will not executed if command1 or command2 failed. (when comman1 fails, the command2 will don't execued (fail) so command3 not executed too.
Play with the next
run() {
echo "comand-$2($1)"
return $1
}
ok() {
run 0 $1
}
fail() {
run 1 $1
}
echo "OK && OK && ANY"
ok A && ok B 0 && ok C
echo
echo "OK && FAIL && ANY"
ok A 0 && fail B 1 && ok C
echo
echo "FAIL && ANY && ANY"
fail A && ok B && ok C
echo
echo "OK || ANY || ANY"
ok A || ok B || ok C
echo
echo "FAIL || OK || ANY"
fail A || ok B || ok C
echo
echo "FAIL || FAIL || OK"
fail A || fail B || ok C
echo
echo "FAIL && OK || OK"
fail A && ok B || ok C
echo
the result
OK && OK && ANY
comand-A(0)
comand-B(0)
comand-C(0)
OK && FAIL && ANY
comand-A(0)
comand-B(1)
FAIL && ANY && ANY
comand-A(1)
OK || ANY || ANY
comand-A(0)
FAIL || OK || ANY
comand-A(1)
comand-B(0)
FAIL || FAIL || OK
comand-A(1)
comand-B(1)
comand-C(0)
FAIL && OK || OK
comand-A(1)
comand-C(0)
The last construction is neat, because you can write
command1 && (commands if the command1 is successful) || (commands if not)
Upvotes: 3
Reputation: 8272
The '&&' operator operates in two ways in Bash.
On one hand, it's a conditional operator as you'd expect:
if [ $condition1 ] && [ $condition2 ]
# Same as: if [ $condition1 -a $condition2 ]
# Returns true if both condition1 and condition2 hold true...
if [[ $condition1 && $condition2 ]] # Also works.
# Note that && operator not permitted inside brackets
#+ of [ ... ] construct.
On the other hand, it can be used to concatenate commands, in which case it explicitly checks the return codes of the commands and proceeds down the chain when the value is 0. See the doc.
Upvotes: 2