-7

I want to create a bash script that creates 30 processes of sleep 1000 &. using a while loop and run it.

!/bin/bash

count = 0
while [$count -le 30]

do

count = `sleep 1000& $count +1`
echo $count
done
Kusalananda
  • 333,661
YakyAK
  • 13
  • Put your script into https://shellcheck.net/ fix the obvious errors. Then you can come back here (to this question) with your fixed script and any outstanding issues. – Chris Davies Jan 31 '18 at 18:53

2 Answers2

0

Your code (with my annotations):

!/bin/bash
# missing '#' on line above

count = 0
# assignments should not have spaces around '='
# also, start at 1 or use `-lt` below to get 30 instead of 31 processes

while [$count -le 30]
# '[' and ']' *should* have spaces inside

do

count = `sleep 1000& $count +1`
# I can see what you're getting at, but it's wrong

echo $count
done

# (possibly) missing 'wait'

With spaces around = in the assignment in your code, the shell will interpret the line as "run the utility count with arguments = and 0". That's why you should not have spaces around = in assignments.

[ "$count" -le 30 ] is exactly the same as test "$count" -le 30. In fact, [ is a command (/bin/[, but often built into the shell for speed) that takes the same arguments as the test utility, but that requires an extra last argument that should be ]. That's where the space requirements of [ and ] comes from.

There should be a call to wait at the end of the script. The wait utility will wait for all background tasks (your sleep 1000 calls) to finish. Without the wait you will start 30 processes that will be left running in the background when the script ends. This may be what you want though.

Corrected code:

#!/bin/bash

count=0

while [ "$count" -lt 30 ]; do
    sleep 1000 &
    count=$(( count + 1 ))
    echo "$count"
done

wait

Alternatively,

#!/bin/bash

for (( count = 0; count < 30; ++count )); do
    sleep 1000 &
    echo "$count"
done

wait

Sometimes you'd see something like

for count in {0..29}; do
    sleep 1000 &
    echo "$count"
done

wait

... but I do not personally like that type of loop since the shell must expand {0..29} into the list 0 1 2 3 4 ... 29 before the loop starts. I think it's inelegant, but that's a personal opinion.

I have used echo "$count" in my code above. Usually when outputting variable data I'd use printf since that's generally safer:

printf '%d\n' "$count"

See e.g. Why is printf better than echo?

I have also quoted the expansion af $count throughout. One could argue that this is not needed since we know exactly what values the variable will have, but it's a good practice nonetheless. See e.g. Security implications of forgetting to quote a variable in bash/POSIX shells

Proper indentation helps with reading, too.

Kusalananda
  • 333,661
0

Here is my version.

~$ num=1; while ((num<=30)); do sleep 1000 & ((num++)); done

~$ pgrep sleep | wc -l 30

A number can be auto-incremented with ((num++)).

jbrock
  • 1,141