Search code examples
bashfor-loopsleep

Linux bash script - for loop one-liner sleep with timeout and multiple variables - syntax problem


I want to make a wait syntax in my shell script until something else is done.

I would like to make it as flexible as possible so that if I need it again for something else I just have to change the numbers.

What I've got so far is:

    #! /bin/bash
    for i in $(seq 1 20); do sleep 0.2; [ $i = 19 ] && echo "19" || echo $i; done

My target result should look something like this:

    for i=0 iStart=1 iEnd=20 iGoal=19 iDuration=2 in $(seq $iStart $iEnd); do sleep $(echo "scale=3; $iDuration / $iEnd" | bc ); [ $i = $iGoal ] && echo "${iGoal} !!!" || echo $i; done

Problems I have / description:

  • I don't know how to define multiple variables in the for loop:
  • $i = counter
  • $iStart = range start for seq
  • $iEnd = range end for seq
  • $iGoal = target number for if condition
  • $iDuration = total time in seconds until timeout reached (exit 1 or whatever) where I take the avg value per pass:
  • I don't know much about rounding numbers in bash scripts, so I'm not sure how I can achieve a solution that is as bash-compatible as possible
  • It would be great if the result would work for as many bash variants as possible.

Maybe I also could put the calculation inside the initial definitions for a little performance gain but I do not care much atm.

The final result:

echo $(date +"%T.%N"); iStart=1; iEnd=20; iGoal=19; iDuration=2; iSleep=$(bc <<<"scale = 3; ${iDuration} / ( ${iEnd} - ${iStart} + 1 )"); for i in $(seq "$iStart" "$iEnd"); do sleep "$iSleep"; if [ "$i" -eq "$iGoal" ]; then echo "${iGoal} goal"; else echo "$i"; fi; done; echo $(date +"%T.%N")

Solution

  • You can put variable assignments at the beginning of a command.

    iStart=1 iEnd=20 iGoal=19 iDuration=2 iSleep=$(bc <<<"scale = 3; "$iDuration" / ("$iEnd" - "$iStart" - 1)") for i in $(seq "$iStart" "$iEnd"); do sleep "$iSleep"; [ "$i" = "$iGoal" ] && echo "$iGoal" || echo "$i"; done