23

How is it possible to run multiple commands and background them using bash?

For example:

$ for i in {1..10}; do wait file$i &; done

where wait is a custom binary.

Right now I get an error:

syntax error near unexpected token `;'

when running the above command.

Once backgrounded the commands should run in parallel.

5
  • 1
    Am ashuming your not referring to: nohup allowing you to execute a command in the background Mar 23, 2016 at 16:03
  • 3
    The error you're seeing is due to & and ; are both "command terminators". You don't need to use both: for ...; do wait $arg & done will work. Mar 23, 2016 at 16:07
  • @glenn jackman. Yes, I actually tried it after posting the question. There is no need for both ; and &
    – Sebi
    Mar 23, 2016 at 16:08
  • 3
    For future readers, a link to the documentation: "A list is a sequence of one or more pipelines separated by one of the operators ‘;’, ‘&’, ‘&&’, or ‘||’, and optionally terminated by one of ‘;’, ‘&’, or a newline." (emphasis mine) Mar 23, 2016 at 16:12

4 Answers 4

32

The &, just like ; is a list terminator operator. They have the same syntax and can be used interchangeably (depending on what you want to do). This means that you don't want, or need, command1 &; command2, all you need is command1 & command2.

So, in your example, you could just write:

for i in {1..10}; do wait file$i & done

and each wait command will be launched in the background and the loop will immediately move on to the next.

4

For the sake of compatibility use the posix form instead of expansion:

for i in $(seq 1 10); do (./wait file$i &); done
1
  • 2
    Note that seq is not a POSIX command and is generally only found on GNU systems. The behaviour or $(...) (and $i) depends on the current value of $IFS. Also note that by doing (cmd &), cmd will be a child of a subshell, so you won't be able to wait for and get its exit status for instance. Mar 23, 2016 at 20:32
2

You can group the commands and put the grouped commands in background. Like :

$ for i in {1..10}; do ((wait file$i)&); done
2
  • There is no need to use the inner parentheses...
    – marc
    Mar 23, 2016 at 15:44
  • only need to use the inner parentheses if you want to put in the background multiple commands as asked in the question. Like ((sleep 1; wait file$i)&);
    – magor
    Mar 23, 2016 at 16:17
2

Is your binary really named wait? I don't recommend to do so, because wait is a shell builtin.

I believe bash doesn't parse well a one-line loop that launches background processes. I suggest you to change the code to:

$ for i in {1..10}; do ./wait file$i & echo "Running 'wait' using PID=$!..."; done

Your Answer

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

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