Is there a difference between how two ampersands and a semi-colon operate in bash?

If I wanted to run two separate commands on one line, I could do this:

cd /home; ls -al

or this:

cd /home && ls -al

And I get the same results. However, what is going on in the background with these two methods? What is the functional difference between them?


The ; just separates one command from another. The && says only run the following command if the previous was successful

cd /home; ls -al

This will cd /home and even if the cd command fails (/home doesn't exist, you don't have permission to traverse it, etc.), it will run ls -al.

cd /home && ls -al

This will only run the ls -al if the cd /home was successful.


a && b

if a returns zero exit code, then b is executed.

a || b

if a returns non-zero exit code, then b is executed.

a ; b

a is executed and then b is executed.


cd /fakedir; ls -al

Runs ls in the current directory because cd /fakedir will fail and the shell will ignore the exit status that is not zero.

cd /fakedir && ls -al

Because the && operator will only continue if the previous command exited normally (status of zero), no ls operation will be performed.

There are other operators, such as & which will background a process. While often placed at the end of a command, it can be put in the middle of a chain.


You can also join them together like an if..then..else for chaining command logic.

example:

ls file.ext && echo "file exists" || echo "file does not exist"