246

What is the difference between

echo "Hello " ; echo "world"

and

echo "Hello " && echo "world"

Both seems to run the two commands after each other.

4
  • 11
    In the second case, (&&), echo "world" is only executed if and only if echo "Hello " returns an exit status of zero.
    – jasonwryan
    Commented Feb 27, 2015 at 8:00
  • 3
    To illustrate the difference, try test -f /etc/passwdx && echo hello versus test -f /etc/passwdx ; echo hello (you may substitute any file you want, existing or non-existing).
    – user
    Commented Feb 27, 2015 at 10:46
  • 18
    While I agree that the other question cited is, perhaps, technically a duplicate of this one, I contend that the wording of this question is far more useful to new users of Linux, who would not have the experience or knowledge to search for "control and redirection operators".
    – Wilson F
    Commented Jun 5, 2018 at 23:55
  • 1
    gnu.org/software/bash/manual/html_node/Lists.html
    – Roland
    Commented Apr 9, 2020 at 14:36

3 Answers 3

287

echo "Hello" ; echo "world" means sequentially run echo "world" no matter the exit status of the previous command echo "Hello". In other words, echo "world" will run irrespective of success or failure of the prior command echo "Hello".

In case of echo "Hello" && echo "world", echo "world" will only run if the first command (echo "Hello") is a success (i.e. exit status 0). This is called short circuit evaluation.

The following examples show how the shell handles command chaining with different operators:

$ false ; echo "OK"
OK
$ true ; echo "OK"
OK
$ false && echo "OK"
$ true && echo "OK"
OK
$ false || echo "OK"
OK
$ true || echo "OK"
$

The final case doesn't print OK because it was short circuited by true.

In short, ; is a separator, && is logical AND, || is logical OR (read more here).

5
  • 58
    Nobody seems to mention that "&&" like in most programming languages means logical "and" and "||" is logical "or". The second one doesn't have to be evaluated to know that "false and whatever = false", so it just isn't evaluated. That's standardized behaviour of logical operators in almost all languages - the second operand is only evaluated if its true/false value makes a difference. The side effect is, that you can write stuff like test && echo success || echo fail.
    – orion
    Commented Feb 28, 2015 at 14:20
  • 14
    And that common programming language behavior of halting evaluation of logical operators if the result is already determined is called "short circuit" evaluation.
    – Will
    Commented Feb 10, 2016 at 18:30
  • 1
    on a bitwise truthy level -- && is multiplication and || is addition and helps to keep operation precedence straight. eg true && false || true is 1 * 0 + 1 and any resultant positive number is truthy; 0 is falsey
    – neaumusic
    Commented Oct 19, 2020 at 23:56
  • @orion But in shell, there aren’t really booleans; false and true are commands that always fail or always succeed, respectively. && and || execution is based on exit status, not on boolean value, but it is quite analogous to “and” and “or” in other programming languages. Note that operator precedence is also different to most programming languages: true || echo 2 && echo 1 is not grouped as true or (print 2 and print 1), as (only) 1 is printed. In shell, it’s evaluated left to right instead. Commented Jan 9, 2021 at 17:03
  • the reason why there is no "OK" echo'd in the statement true || echo "OK" is because the || operator only evaluates up to the first true statement and doesn't eval any further. This is called "logical short ciruiting"
    – JDOaktown
    Commented Jun 5, 2023 at 16:14
21

Every command in Linux returns an exit code when it finishes running. The exit code is assigned to a special variable ?, so you can easily check the status of last command, e.g. by echo $?. This is often utilised in scripts. If the command finishes successfully, it returns an exit code 0, whereas if there are any errors during the execution, the exit status is non-zero. See example below:

$ echo "Hello"
Hello
$ echo $?
0

$ rm nonexistent-file
rm: cannot remove ‘nonexistent-file’: No such file or directory
$ echo $?
1

Now, this leads us to your question. The && is a special operator that says 'execute the next command only if the previous command was successful, i.e. returned with an exit code of zero'. There is also a reverse operator ||, which only executes the following command if the previous command failed, i.e. exited with non-zero. See example below:

$ echo "Hello" && echo "Previous command was successful"
Hello
Previous command was successful

$ rm nonexistent-file && echo "This will not be printed"
rm: cannot remove ‘nonexistent-file’: No such file or directory

$ rm nonexistent-file || echo "But this will be shown"
rm: cannot remove ‘nonexistent-file’: No such file or directory
But this will be shown

EDIT: The qustion was about the difference betweem && and ; so for this to be a full answer I need to add that a semicolon simply divides one command from another. No checking of the exit code takes place, so if you have several commands separated by semicolons, they are simply executed sequentially, i.e. one after another, completely independently from each other.

1
8

In addition to @heemayl's answer, && (and also ||) will result in the shell only handling a single exit code for all the chained commands. So if you have a trap [...] ERR or set -o errexit line it will process all the commands before doing the exit code handling.

Not the answer you're looking for? Browse other questions tagged .