That's:
if
first list of commands
then
second list of commands
else
third list of commands
fi
That's to run the second list of commands if the first list of commands returns with a true/success (zero) exit status, that is if the last run command in there returns with a zero exit status.
In:
var=-2 && ((var += 2))
It's cmd1 && cmd2
where cmd2
is only run if cmd1
is successful.
var=-2
Will typically be successful as long as $var
has not been made read-only, so the ((var += 2))
command will be run:
((arithmetic expression))
Returns success/true as long as the expression is correctly evaluated (no syntax error) and the result of the expression is non-zero.
((123))
, ((1 + 1))
, ((1 == 1))
return true
((0))
, ((-2 + 2))
, ((2 == -2))
return false.
((4294967296 * 4294967296))
return false in most shells because of 64 bit integer wrapping
var += 2
as an arithmetic expression, performs the assignment and resolves to the value being assigned, here 0, hence the false exit status.
You can see the value upon which is based the exit status, by using the $((...))
arithmetic expansion syntax:
$ echo "$((1 + 1)) $((2 == 2)) $((2 == -2)) $((var = -2)) $((var += 2))"
2 1 0 -2 0
Or assigning it to a variable:
$ var=-2; ((result = (var += 2)))
$ echo "$? $result $var"
1 0 0
$?
contains the exit status of the previous command. As far as if
/then
/else
/fi
is concerned, 0 means true, anything else means false.
The confusion here comes from the fact that for arithmetic expressions, it's the other way round: 0
means false and anything else means true (for instance, 2 == 2
is 1
while 2 < 1
is 0
).
To avoid worrying about the difference, just forget about $?
and its possible values. Just think in terms of boolean true/false, sucess/failure.
grep -q foo file
Returns true if foo
is found in file
.
[ "$a" = "$b" ]
Returns true if $a
contains the same thing as $b
.
((6 * 3 - 12))
((4 == 1))
Return true if the result of the arithmetic expression is a non-zero number.
It doesn't matter whether those true/false are expressed in terms of 0 or 1 of the exit status of those grep
/[
commands or ((...))
construct.
Best Answer
This will echo
127
, the correct error code for "command not found".You can use
local
to define more than one variable. So I just also create the local variableRET
to capture the exit code of the subshell beforelocal
succeeds and sets$?
to zero.