In fish shell, && and and seem to behave the same way. Are they exactly the same? And are there any edge cases in which they would behave differently?
In fish shell, && and and seem to behave the same way. Are they exactly the same? And are there any edge cases in which they would behave differently?
and/&& and or/|| and not/! are the same thing, except for operator precedence and whether they can be put on a new line.
Imagine:
echo 1 || echo 2; and echo 3
the || binds first, so echo 1 || echo 2 is considered one thing. It prints "1", that succeeds so it skips printing "2", then because the || on the whole succeeded prints "3".
While
echo 1; or echo 2 && echo 3
will print just "1". echo 1 succeeds so the entire rest is ignored.
Also the ";" for ; and and ; or can be replaced with a newline, while && and || can't be put on a new line (without escaping the end of the previous line):
# valid
echo 1
and echo 2
# invalid
echo 1
&& echo 2
# valid - note the `\` is the last thing on the line
echo 1 \
&& echo 2
Other than those things (and any bugs), these are the same.
While they're used for the same thing, they are fundamentally quite different:
sh && is a binary operator that takes two commands, runs the first, and only if it succeeds, runs the second. The exit status is that of the first command if it fails, or the second command if it doesn't.
fish and is a unary operator that takes a single command, and runs it if $status is 0. The exit status is optionally modified by the command if run.
Here you can see the difference in arity:
$ fish -c 'and echo true'
true
$ sh -c '&& echo true'
sh: 1: Syntax error: "&&" unexpected
Here you can see how and may operate on a command that's not immediately before it:
$ fish -c 'false; set x 1; and echo true'
(no output)
$ sh -c 'false; x=1 && echo true'
true