Is there a difference between the '&&' and ';' symbols in a standard BASH terminal?

They seem to both signal BASH to commence with another command following the symbols but is there a distinct difference?

6 Answers

With this line:

command1 && command2

command2 will be executed if (and only if) command1 returns exit status zero, whereas in this line:

command1 ; command2

both command1 and command2 will be executed regardless. The semicolon allows you to type many commands on one line.

1

You can try the difference for yourself:

  1. ls /invalid/path && echo "hello!"
    since /invalid/path doesn't exist, ls can't show you the directory listing. It will fail with an error message: "ls: /invalid/path: No such file or directory".
    The second half of the command (echo "hello!") is never even executed because the first half failed.

  2. ls /invalid/path ; echo "hello!"
    The same error message appears as before, but this time, the second part is executed!
    ls: /invalid/path: No such file or directory
    hello!

Why is this useful?
Suppose you want to extract a file called archive.tar.gz
You could use the command tar zxvf archive.tar.gz && rm archive.tar.gz.
If for any reason the extraction of the archive fails, the second part isn't executed! You can try again.

If you use ; in the same situation, the archive is deleted and you can't try again.

0

&& is AND, meaning that the second command will only execute if the first one returned true (no errors).

8

Update: I've added as script to highight some of the possible traps:

Because no-one else has mentioned "||", I will

Update2: some important re-wording here
&& is like a "then" of an "if" statement which responds to "true"

|| is NOT like the "else" of an "if" statment..
|| is like a "then" of an "if" statement which responds to "false"

More specificaly, && tests the $? return value of the previous most recently executed statement and passes control to the statement or sub-shell immediately following the &&... it only passes control if $? is true.

|| is similar, and is often seen following a && statement, but it tests for a false return value ($?) from the previous most recently executed statement... NB!, Nota Bene! Note well!.... if the predecing statement is an && statement which retruns false when you expect it to be true, then || will respond to the false, so mixing both on the same line may be risky

The main point I am trying to make is in relation to a mistake I made. ie:
## [[condition]] && A || B
is not does not behave like a C/C++ style ternary. ie:
// (condition) ? A : B
See the script below for examples of "unexpected" results from "A"

The basic test and the && and the || statement must all be on the same line...


Run this script to see where things can go wrong when using && and ||
The most recently executed statement may not be the one you expect..

[[ condition]] && echo Hello || echo Goodbye .... is typically safe,
becaue a well formed echo will return true.
but what about accessing a file which doesnt exits?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo ====== ((1==1)) && echo " ((1==1)) rc=$? ..&&.. condition is true" || echo " ((1==1)) rc=$? ..||.. condition is false" $0 0 && echo " \$0 0 rc=$? ..&&.. condition is true" || echo " \$0 0 rc=$? ..||.. condition is false" ((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && echo " \$0 1 rc=$? ..&&.. condition is true" || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair'
echo ====== ((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false" $0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false" ((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo ====== ((1==1)) || echo " ((1==1)) rc=$? ..||.. condition is true" && echo " ((1==1)) rc=$? ..&&.. condition is false" $0 0 || echo " \$0 0 rc=$? ..||.. condition is true" && echo " \$0 0 rc=$? ..&&.. condition is false" ((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false" $0 1 || echo " \$0 1 rc=$? ..||.. condition is true" && echo " \$0 1 rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair'
echo ====== ((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false" $0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false" ((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
exit 

0

try

false && echo "hello"

and

false ; echo "hello"

see the difference

The command (function, in case of a script) after && is executed depending upon the RETVAL of the first command (function, in case of a script). It forces the first command to return a value of 0, if successful. We can check the return value to execute further commands.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like