Home > Enterprise >  Convert for loop to while loop in bash script
Convert for loop to while loop in bash script

Time:11-20

I have a for loop as follows:

mapfile -t ipLast < SippIPs.txt

echo "   ----  SIPp ----  "
echo "Please give count of SIPps needed to generate calls.."
read -p 'Sipps count starts from: ' start; read -p 'Sipps count ends on: ' end
if [[ -z $start ]] || [[ -z $end ]]; then echo "User pressed ENTER with no input text"; fi

for ((j=$start; j<=$end; j  )); do
        sipps=${j[@]}
        ipList=(${ipLast[sipps-1]})
        if [[ "$end" -eq 0 ]]; then
                echo "No way it cannot end on 0"
                exit
        fi

        echo "    ----  Launching SIPp $sipps ----  "
        sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@$ipList <<EOF1
        pkill -f sipp

        screen -S sipp -d -m bash -c 'cd /usr/local/src/sipp-3.3; ulimit -Hn 65535; ulimit -Sn 65535; ./sipp -i $ipList -mi $ipList -sf HA_demo.xml -inf HA_demo.csv 10.171.0.231:5060 -p 5060 -r 1 -rp 1s -l 1 -m 1 -watchdog_minor_threshold 1500 -watchdog_major_threshold 4000 -watchdog_major_maxtriggers 30 -trace_err -aa -d 350s -oocsn ooc_default -t u1 -trace_screen -skip_rlimit && exec bash'
        exit
EOF1
done

I want to convert the for loop to while loop such that after giving the count it returns to the loop to ask the user if they want to quit or keep launching SIPp.

My try:

mapfile -t ipLast < SippIPs.txt
read -p 'Sipps count starts from: ' start; read -p 'Sipps count ends on: ' end

j=$start
while (j<=$end); do
        sipps=${j[@]}
        ipList=(${ipLast[sipps-1]})
        if [[ "$end" -eq 0 ]]; then
                echo "No way it cannot end on 0"
                exit
        fi

        echo "    ----  Launching SIPp $sipps ----  "
        sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@$ipList <<EOF1
        pkill -f sipp

        screen -S sipp -d -m bash -c 'cd /usr/local/src/sipp-3.3; ulimit -Hn 65535; ulimit -Sn 65535; ./sipp -i $ipList -mi $ipList -sf HA_demo.xml -inf HA_demo.csv 10.171.0.231:5060 -p 5060 -r 1 -rp 1s -l 1 -m 1 -watchdog_minor_threshold 1500 -watchdog_major_threshold 4000 -watchdog_major_maxtriggers 30 -trace_err -aa -d 350s -oocsn ooc_default -t u1 -trace_screen -skip_rlimit && exec bash'
        exit

        j  
EOF1
done

CodePudding user response:

The immediate problem is that you need double ((...)) for an arithmetic evaluation. The expression (j<=$end) attempts to run the program j in a subshell with input from the file =$end.

Also, executing j on the remote host obviously will not update the local variable j even if you fix the syntax. You apparently want something like

j=$start
while ((j<=$end)); do
    :
    sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@$ipList <<EOF1
        :
EOF1
    ((j  ))
done

The expression sipps=${j[@]} looks quite odd; j is not an array.

Anyway, there is no particular need to switch from a for loop to a while loop here; just break out of the loop if the user indicates that they want to stop looping.

The screen shenanigans look like you are probably Doing It Wrong but without more information about "it" it's hard for us how to suggest any changes. The exec bash is dubious; what should this code actually accomplish?

exit is redundant at the end of a script; the shell will always exit when it finishes executing the script. Perhaps review Pass commands as input to another command (su, ssh, sh, etc)

As always, you will want to avoid using read -p to receive parameters; a much superior design is to have the caller specify the start and end of the range to scan as command-line arguments. Then start will be $1 and end will be $2 (assuming you have no other command-line processing).

CodePudding user response:

So this is what I was looking for:

while :
        mapfile -t ipLast < SippIPs.txt
        read -p 'Sipps count starts from: ' start; read -p 'Sipps count ends on: ' end
        if [[ -z $start ]] || [[ -z $end ]]; then echo "User pressed ENTER with no input text"; fi
        echo "   ----  SIPp ----  "
        echo "Please give count of SIPps needed to generate calls.."
do
        for ((j=$start; j<=$end; j  )); do
                sipps=${j[@]}
                ipList=(${ipLast[sipps-1]})
                if [[ "$end" -eq 0 ]]; then
                        echo "No way it cannot end on 0"
                        exit
                fi

                echo "    ----  Launching SIPp $sipps ----  "
                sshpass -p "root12" ssh -tt -o StrictHostKeyChecking=no root@$ipList <<EOF1
                pkill -f sipp

                screen -S sipp -d -m bash -c 'cd /usr/local/src/sipp-3.3; ulimit -Hn 65535; ulimit -Sn 65535; ./sipp -i $ipList -mi $ipList -sf HA_demo.xml -inf HA_demo.csv 10.171.0.231:5060 -p 5060 -r 1 -rp 1s -l 1 -m 1 -watchdog_minor_threshold 1500 -watchdog_major_threshold 4000 -watchdog_major_maxtriggers 30 -trace_err -aa -d 350s -oocsn ooc_default -t u1 -trace_screen -skip_rlimit && exec bash'
                exit
EOF1
        done
        read -p 'Do you want to perform failover..(y/n)' cc
        if [[ $cc == "y" || $cc == "y" ]]; then
                exit
        fi
done

Thanks for the help!

  • Related