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.

5
  • 1
    Am ashuming your not referring to: nohup allowing you to execute a command in the background Commented 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. Commented 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
    Commented 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) Commented Mar 23, 2016 at 16:12

4 Answers 4

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.

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. Commented 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
    Commented 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
    Commented 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .