-6

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
  • 3
    Why? Is this is a homework or some other learning exercise? Have you tried something already? – ilkkachu Jan 31 '18 at 14:55
  • Kind of homework, I tried something but I think this is not exactly what I am required to do – Yakir Ben Harosh Jan 31 '18 at 14:57
  • 4
  • @YakirBenHarosh Do not worry, show us what you tried. There are so many ways to do this, help us to help you. – andcoz Jan 31 '18 at 15:08
  • Edited my questions, Sorry about the misunderstanding.@andcoz @ilkkachu – Yakir Ben Harosh Jan 31 '18 at 16:25
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.

  • Wow, thank you very much about the elaborated answer. really appreicated a lot. thanks buddy! – Yakir Ben Harosh Jan 31 '18 at 20:54
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++)).

  • Not deprecated, but not maybe in high fashion. – Kusalananda Jan 31 '18 at 22:18
  • @Kusalananda Thank you for your comment. You're right. I did some research and could not find anything about the -lt, -gt, etc. operators being deprecated. They are just older than the double parentheses ones. I have updated my answer. – jbrock Feb 1 '18 at 0:05

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.