What will happen if I write a line in bash like
commandA && commandB ; commandC
commandA fails, will
commandC be executed?
Yes, and you can easily check it yourself:
$ non-existent-command && echo hi ; echo after semicolon bash: non-existent-command: command not found after semicolon
man bash it says:
Commands separated by a ; are executed sequentially; the shell waits for each command to terminate in turn.
commandC will be executed no matter if
commandB fails or succeeds.
Semicolon is just a separator to make commands execute sequentially. The only scenario that I can see where
commandC will fail, is if
exit commands (or any command like
exec (or functions that call those) that forcefully affects the work flow):
[root@host ~]# exit && echo "HI"; echo "test" logout [user@host ~]$
[root@host~]# echo "HI" && exit; echo "test" HI logout [user@host ~]$
tl;dr: Is not that those characters have a precedence. They mean different things. One is a logical operator and the other is a list terminator.
What are the shell's control and redirection operators? This answer gives a good explanation about the bash operators. Quoting a little piece of the answer:
;: Will run one command after another has finished, irrespective of the outcome of the first.
command1 ; command2
command1is run, in the foreground, and once it has finished,
command2will be run.
A newline that isn't in a string literal or after certain keywords is not equivalent to the semicolon operator. A list of
;delimited simple commands is still a list - as in the shell's parser must still continue to read in the simple commands that follow a
;delimited simple command before executing, whereas a newline can delimit an entire command list - or list of lists. The difference is subtle, but complicated: given the shell has no previous imperative for reading in data following a newline, the newline marks a point where the shell can begin to evaluate the simple commands it has already read in, whereas a
;semi-colon does not.
Semicolons superfluous at the end of a line in shell scripts? Quoting the answer:
Single semicolons at the end of a line are superfluous, since the newline is also a command separator.
casespecifically needs double semicolons at the end of the last command in each pattern block; see
help casefor details.
per the bash man page
[L]ist operators, && and || have equal precedence, followed by ; and &, which have equal precedence.
In practice this boils down to who cares about the return result. If the result is need right away it has higher precedence.
As other posts have said, the short answer is
commandC will be executed regardless of what else happens.”
As nwildner explored, the longer answer is,
commandC will be executed regardless of what else happens,
as long as the shell is still in a condition
in which it can execute
In other words, the shell will not proceed beyond the
commandA && commandB ; command
command line without executing
kill -KILL $$
or something else that terminates or cripples the shell,
or disrupts the command flow, then
commandC will not be executed.
(Clearly we’re talking about edge cases here.)
Behavior is a little different if
set -o errexit) has been issued:
commandCwill be executed (but
commandBwill not be).
commandBwill be executed.
commandCwill be executed.
commandBfails, the shell will exit, and
commandCwill not be executed.
errexit option specifies that the shell shall exit
if any command (any “pipeline”) fails, with some exceptions:
The shell does not exit if the command that fails is part of the command list immediately following a
untilkeyword, part of the test following the
elifreserved words, part of any command executed in a
||list except the command following the final
||, any command in a pipeline but the last, or if the command's return value is being inverted with
— from bash(1)
commandA fails, that just causes
commandB not to be executed,
commandA is followed by
commandB runs and fails, it causes the shell to exit,
because it (
commandB) follows the (final)