Sequencing in a bash for loop and displaying 01 02 ... instead of 1 2

linux
screen
bash

#1

Hello,
I have the following bash script:

#!/usr/bin/env bash
shopt -s nullglob
for ((i=$1;i<=$2;i++))
do
    /usr/bin/screen -4 -d -m -S script_worker$i /backend/production/script_worker$i.sh
done

I need to pass in two parameters such as follows:

bash test.sh 01 15

and have the for loop generate a sequence such as

01
02
03
...
10
11
12

How do i fix the code in order to prefix the values less than 10 with a 0 in order to generate a series of statements such as

/usr/bin/screen -4 -d -m -S script_worker01 /backend/production/script_worker01.sh
/usr/bin/screen -4 -d -m -S script_worker02 /backend/production/script_worker02.sh
/usr/bin/screen -4 -d -m -S script_worker03 /backend/production/script_worker03.sh
...
/usr/bin/screen -4 -d -m -S script_worker10 /backend/production/script_worker10.sh
/usr/bin/screen -4 -d -m -S script_worker11 /backend/production/script_worker11.sh

Thanks for you help.
Mark


#2

You can also use {01…10} syntax:

echo {01..03}
echo {1..3}

Try:

#!/usr/bin/env bash
for i in {01..10}
do
	/usr/bin/screen -4 -d -m -S script_worker${i} /backend/production/script_worker${i}.sh
done

#3

#4

this seems to work:

#!/usr/bin/env bash
shopt -s nullglob
for ((i=$1;i<=$2;i++)) do
  if [[ $i -lt 10 ]] ; then
    echo /usr/bin/screen -4 -d -m -S script_worker0$i /backend/production/script_worker0$i.sh
  else
    echo /usr/bin/screen -4 -d -m -S script_worker$i /backend/production/script_worker$i.sh
  fi
done

#6

Here is an updated code for you:

#!/usr/bin/env bash
START=$1
END=$2
for i in $(eval echo "{$START..$END}")
do
	/usr/bin/screen -4 -d -m -S script_worker${i} /backend/production/script_worker${i}.sh
done

Run it as follows:

script 01 15

#7

i would not use eval in this case , since you don’t check the input for $1 and $2
there lots of better ways to do it , and i think this one is better

    #!/usr/bin/env bash
    shopt -s nullglob
    for i in $(seq -w "$1" "$2")
    do
        /usr/bin/screen -4 -d -m -S script_worker"$i" /backend/production/script_worker"$i".sh
    done

script 1 15 or script 01 15 does the same thing in this case


#8

You can always add simple condition to check for $1 and $2:

#!/bin/bash
die(){
  echo "Syntax: $0 start end"
  exit 1
}

[ -z "${1}" ] && die
[ -z "${2}" ] && die

for i in $(eval echo "{$START..$END}")
do
	/usr/bin/screen -4 -d -m -S script_worker${i} /backend/production/script_worker${i}.sh
done

Of course seq method works too.


#9
for ((i=10#$1;i<=10#$2;i++))
do
   printf -v y '%02d' $i
   screen ... $y...

#10

How does this works? I mean 10#$1 ? This is a weird syntax. Never seen before.


#11

This kind of reminds me of ${VAR-DEFAULT} syntax:

for ((i=${1-10};i<=${2-10};i++))

but no, something is going on… AHAH:

○ → declare -i i; i=10#20; echo $i
20

○ → declare -i i; i=16#20; echo $i
32

X#Y forces Y to be interpreted as base X! TIL.