24

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.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Sebi
  • 1,009

4 Answers4

34

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.

terdon
  • 242,166
4

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

for i in $(seq 1 10); do (./wait file$i &); done
marc
  • 2,427
  • 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. – Stéphane Chazelas Mar 23 '16 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
magor
  • 3,752
  • 2
  • 13
  • 28
  • There is no need to use the inner parentheses... – marc Mar 23 '16 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 '16 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