Bash $? Variable assignment
I just started learning bash and I was reading about variable$?
. From what I understand, the $?
exit status of the last command executed is assigned.
for example
$ false; echo $?
Will give way to 1 and
$ false; :; echo $?
Will get 0
Things get a little more complicated when I combine them with if / for blocks. The man page reads:
for
NAME [in
WORDS ...];
do
TEAM;
done
Execute commands for each member on the list.
The loop
for
runs a sequence of commands for each member in the list of items. Ifin WORDS ...;
not, thenin "$@"
it is assumed. For each element in WORDS, NAME is set to that element and COMMANDS are executed.Exit status:
Returns the status of the last command executed.
It means:
$ false; for i in 1 2 3; do false; done; echo $?
Will give way to 1, since the last executed command is false. But
$ false; for i in; do false; done; echo $?
or
$ false; if false; then :; fi; echo $?
Will give way to 0, despite the fact that the last command was executed.
My guess is that the variable $?
has a value of 0 when the for / if block is entered. Did I miss something?
According to the bash manual :
if
list;then
list; [elif
list;then
list; ] ... [else
list; ]fi
In progress
if
list
. If its exit status is zero, executedthen
list
. Otherwise, eachelif
list
is executed in turn, and if its exit status is zero, the corresponding is executedthen
list
and the command terminated. Otherwise, executedelse
list
if present. The exit status (of the whole blockif ... fi
) is the exit status of the last command (inthen
,elif
orelse
) , or zero if the condition is not checked true.
yes, after if ..;
, for ..;
or while ..;
outputs the reset status to 0.
to be clear, it doesn't mean after fi;
or done;
because the exit status is the last exit status of the command.
EDIT: The commands between if
/ elif
and then
do not affect the exit status of the compound statement, whereas the last command executed between then
/ else
and elif
/ fi
sets the exit status of the compound statement.
after calling the function; the exit status will be the value returned return
or the exit status of the last command.
with the option set -e
, set -o errexit
; the shell exits after a command with an exit status of <> 0, unless it follows ||
or inside a statement if ..;
.
exit status should be checked immediately after the command output, you can use Boolean operators &&
, ||
:
# to fail fast the process can't continue
simple_command || {
echo "failed .."
exit 1
}
is error handling similar to errors, a question to be asked, or a way to continue the process after the command fails?
in pipeline commands, the exit status is the exit status of the last command, except set -o pipefail
: the exit status will be the exit status of the last command in the pipe with the exit status <> 0.
The command $ false; for i in; do false; done; echo $?
gives the exit status for loop
. Since it exits the loop without error, it $?
is 0. Here is a similar question that might be helpful.
How to get completion status in a loop in bash