22

This question already has an answer here:

When you want to run multiple commands you can use ;, && and |

Like this: killall Finder; killall SystemUIServer, cd ~/Desktop/ && rm Caches Or: man grep | man cat for example.

But, is there a difference between |, ; and &&? If so, what is the difference?

marked as duplicate by Gilles bash Oct 6 '14 at 19:21

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    Sorry, but have you tried man bash? – Martin Schröder Oct 6 '14 at 12:02
  • 2
    That man page is gigantic and can be daunting to someone new to bash. – Anthony Oct 6 '14 at 14:23
  • 1
    It's trivial to find when searching, e.g. && is explained in the paragraph containing the second match. – Daniel Beck Oct 6 '14 at 16:10
  • 3
    No, this was asked 20 hours ago, his question was asked 16 hours ago. That question is a duplicate of mine. – DisplayName Oct 6 '14 at 18:53
  • 2
    Displayname - I think your question is the better of the two - it is not singly focused on bash as is the other. I also find it strange that a question with an answer garnering 34 votes - as @jimmij's has - should be so easily dismissed. I noted my own disapproval in this answer to terdon's meta question and - for what little it is likely to be worth - I have voted to reopen this question. – mikeserv Oct 6 '14 at 21:42
61
  • ;: commands separated by a ; are executed sequentially. The shell waits for each command to terminate in turn.

  • &&: command after && is executed if, and only if, command before && returns an exit status of zero. You can think of it as AND operator.

  • |: a pipe. In expression command1 | command2 The standard output of command1 is connected via a pipe to the standard input of command2.

There are more similar control operators, worth to mention:

  • ||: command after || is executed if, and only if, command before || returns a non-zero exit status. You can think of it as OR operator. Please note, that | and || are completely different animals.

  • &: the shell executes the command terminated by & in the background, does not wait for the command to finish and immediately returns exit code 0. Once again, & has nothing to do with &&.

  • |&: a shorthand for 2>&1 | i.e. both standard output and standard error of command1 are connected to command2's standard input through the pipe.

Additionally if you use zsh then you can also start command with &| or &!. In this case job is immediately disowned, after startup it does not have a place in the job table.

  • 1
    You might as well add & since & and ; are similar, and your description of ; providing sequential execution provides a good segue into & providing non-sequentialized execution. – Nick Russo Oct 6 '14 at 0:24
  • You are right, I've added it and a few more. – jimmij Oct 6 '14 at 1:03
10

Consider two commands A and B. When you write

A | B

A and B are executed in parallel, and the standard output of A is sent as the standard input of B.

When you write

A; B

A is executed, then B is executed (unless set -e has been used and A terminates with a non-zero exit status, in which case the shell terminates just after A).

When you write

A && B

A is executed, then B is executed only if A has terminated successfully (zero exit status). This form can be safer than the previous one, e.g. with

cd some_dir && rm file*

The && makes sure that the right files are removed, i.e. files are removed only if the cd has succeeded.

6

The other answers already explain |, && and ;, so I'll add something additional you haven't explicitly asked for: ||.

A || B

A is executed, and then B is only executed if A failed. This is useful for reacting on error conditions:

martin@martin ~ % rm doesnotexist 2>/dev/null || echo "failed to delete file"
failed to delete file

(The 2>/dev/null is necessary to hide the error message of rm itself.)

  • 1
    B is executed if A failed, not if B failed – cpast Oct 6 '14 at 3:57
  • @cpast you're right, I mixed it up. Thanks for the heads up. – Martin von Wittich Oct 6 '14 at 10:44
3

All three are rather different from one-another, especially |.

  • |: First of all it's called a 'pipe', and can be used to redirect the output of one program into the other. Your example won't actually do anything meaningful tho because man doesn't use standard input for anything. A more meaningful example would be man grep | grep -- -v which will find '-v' in the output from man grep

  • ;: The semicolon can be used instead of a newline, to make things take up less space.

  • &&: The two ampersand operator is a boolean AND operator which means that the command after the && will be run if, and only if, the command on the left side returns true, which on UNIX systems means that it returned with the exit code 0.

  • This was simple and easily explained. Thank you! – DisplayName Oct 6 '14 at 7:49
2

No one seems to be explaining why you would use each one, given your actual examples. I'll take a stab at it:

killall Finder; killall SystemUIServer

A command like killall can take some time to execute. By using the semicolon, you can give both commands at once and then do something else while you wait. That way you don't have to wait twice (once for each command).

cd ~/Desktop/ && rm Caches

You want to remove the directory ~/Desktop/Caches and end up in the directory ~/Desktop. What you do not want to do is to remove the directory Caches from the current directory (before you change it). So you use && to check that the directory change was successful before you do your remove command.

man grep | man cat

This makes no sense to me. The man command does not process input, so piping things to it won't do anything. Perhaps you meant

man grep || man cat

That would try to find the man page for grep and then if it couldn't, would show the man page for cat. Or possibly you meant

man grep | cat

That would use cat to display the man page rather than the pager (normally less). The | redirects the output from man to the command cat (which just dumps everything to screen). This can be useful in a GUI where you can use the scroll bar to go back and forth in the file rather than using the keyboard commands in less.

Note: if you want to know what ; && | || do in the more general cases, then I'd suggest looking at jimmij's answer. I'm just trying to explain what's happening in the examples from the question.

  • The reason for the commands not making sense is because i just typed out something random, it was not meant to be effective. – DisplayName Oct 6 '14 at 7:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.