113

I try to run a background job in a for loop in bash:

for i in $(seq 3); do echo $i ; sleep 2 & ; done

I get error:

bash: syntax error near unexpected token `;'

In zsh the command line works.

zx8754
  • 52,746
  • 12
  • 114
  • 209
bougui
  • 3,507
  • 4
  • 22
  • 27

3 Answers3

166

Remove the ; after sleep

for i in $(seq 3); do echo $i ; sleep 2 & done

BTW, such loops are better written on separate lines with proper indentation (if you are writing this in a shell script file).

for i in $(seq 3)
do
   echo $i
   sleep 2 &
done
gammay
  • 5,957
  • 7
  • 32
  • 51
  • 6
    Keep in mind that it will send "sleep 2" to background only. – tamerlaha Mar 16 '17 at 11:55
  • Why is it when I do this with `$i` in the backgrounded command, job control says the process name contains `$i` instead of whatever the actual value of `$i` was? – Michael Aug 06 '20 at 22:40
  • @Michael Full program with output would help to understand better – gammay Aug 07 '20 at 06:53
  • `for I in ; do rm -fr $I & done` ... `jobs` -> `rm -fr $I` several times, instead of the actual dir being deleted for each job – Michael Aug 07 '20 at 16:45
  • I have answer for this, its long. So i think you should post it as a new question (and add that question link here), I will answer and you will also get more responses. – gammay Aug 08 '20 at 07:17
51

You can put the background command in ( )

for i in $(seq 3); do echo $i ; (sleep 2 &) ; done
sogart
  • 629
  • 5
  • 5
  • 23
    Please be aware: You create a subshell by that. It also means you will not be able to `wait` for the background jobs to end. – JFK Mar 07 '18 at 07:13
1

If you want to run a block of code in the background, you could do the below. Just put the block of code around the curly braces.

{ for i in $(seq 3); do echo $i ; sleep 2 ; done } &
k_vishwanath
  • 1,326
  • 2
  • 20
  • 28