308

I normally run multiple commands with something like this:

sleep 2 && sleep 3

or

sleep 2 ; sleep 3

but what if I want to run them both in the background from one command line command?

sleep 2 & && sleep 3 &

doesn't work. And neither does replacing && with ;

Is there a way to do it?

1
  • 13
    Use () to surround the command. Commented Jan 30, 2013 at 19:47

7 Answers 7

544

Exactly how do you want them to run? If you want them to be started in the background and run sequentially, you would do something like this:

{ sleep 2; sleep 3; } &

If you want sleep 3 to run only if sleep 2 succeeds, then:

sleep 2 && sleep 3 &

If, on the other hand, you would like them to run in parallel in the background, you can instead do this:

sleep 2 & sleep 3 &

And the two techniques could be combined, such as:

{ sleep 2; echo first finished; } & { sleep 3; echo second finished; } &

Bash being bash, there's often a multitude of different techniques to accomplish the same task, although sometimes with subtle differences between them.

Sign up to request clarification or add additional context in comments.

6 Comments

What happens if we do sleep 2 && sleep 3 & ? I tried it in bash and it seems to work the same way (tried with echo).
@HakanBaba, Yes it does indeed create a subshell in the background.
@Wajahat, Did you try sleep 2 && echo "foo" && sleep 3 & echo "bar"" ? The && operator tells the shell to execute the command before it, and only if that command executes without any error the shell executes the subsequent command. This is essentially different from ;, because ; lets the subsequent command execute regardless of the exit status of the previous command unless it was a fatal error. The & tells the shell to execute all of the "connected" commands preceding it, in the background. "connected" here means the command is part of a pipe ( | ) or a logical operator.
Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence. in bash manual.
For some reason this is not working for me - i=0;while [ $i -le 10 ]; do echo i:$i;i=$[$i+1];sleep 2;done; & j=10;while [ $j -ge 0 ]; do echo j:$j;j=$[$j-1];sleep 2;done; & or (i=0;while [ $i -le 10 ]; do echo i:$i;i=$[$i+1];sleep 2;done; &) ; (j=10;while [ $j -ge 0 ]; do echo j:$j;j=$[$j-1];sleep 2;done; &) gives out -bash: syntax error near unexpected token `&' error. Am i missing something?
|
71

You need to add some parens in your last version --

(sleep 2 &) && (sleep 3 &)

or this also works --

(sleep 2 &) ; (sleep 3 &)

1 Comment

Note : When a list is used with &, its exit status is always zero. So, the two cases above do the same thing(The shell executes both sides in turn asynchronously).
11

to run multiple background command you need to add & end of each command. ex: (command1 &) && (command2 &) && (command3 &)

1 Comment

-1. Joining bg'ed commands with && accomplishes nothing, since they always return zero immediately. That is, it's the same as using ;. What OP wants is (command 1 && command 2) &
7

The answers above use parentheses. Bash also can use braces for a similar purpose:

{ sleep 2 && sleep 3; } &

Note that the braces are more picky about syntax--the space after {, the space before }, and the final semicolon are required. In some situations the braces are more efficient because they don't fork a new subshell. In this case I don't know if it makes a difference.

1 Comment

What about { sleep 2; sleep 3; } &?
4

This works:

$(sleep 2 &) && sleep 3 &

Also you can do:

$(sleep 2 && sleep 3) &

Comments

4

You can use the bash command substitution $(command) like this:

$(command1 ; command2) &

Note that stdin and stdout are still linked to the parent process and redirecting at least the stdout can be tricky. So alternatively you can chain the commands in a single line then pass the string to the bash command to spawn a new process which will handle the execution.

bash -c "command1 ; command2" & 

This is especially useful in a bash script when you need to run multiple commands in background.

These two statements should be equivalent. A bash process is spawn in both cases to handle the command (chain of commands) and the & at the end detaches the execution.

This time you can add &>/dev/null before the & at the end of the command to redirect at least the stdout and avoid the output on the stdout of the parent process. Something like:

bash -c "command1 ; command2" &>/dev/null &

Comments

1

I have the same mission too. I have try (sleep2 ; fg )& sleep3 ; fg,it's working. And when you preass ctrl+c doubled,the two process can be stoppped.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.