-1

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
Asad Javed
  • 57
  • 6

2 Answers2

1

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).

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

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!

Asad Javed
  • 57
  • 6
  • The long list of commands in the `while` condition looks like more unwarranted complexity. The final `echo` will always succeed so this is basically identical to running the commands inside a `while true` loop. – tripleee Nov 19 '21 at 12:43
  • Can you please elaborate a bit? How can I make it short? Actually what the code is doing is it is reading the IPs of SIPp from a text file which is a call generator and looping over those IPs from start to end which is input by the user. Furthermore, using sshpass it accesses the VM and creates a screen so that the SIPp process keeps running. The purpose of screen here is to keep the process running so that it doesn't exit. This is just a part of my bash script so exit is needed so that it can move to the next part of the script. – Asad Javed Nov 19 '21 at 12:59
  • Anything like `while unrelated command; other command; some more commands; this command; true do` is basically identical to `while true; do unrelated command; other command; some more commanbds; this command; ...` – tripleee Nov 19 '21 at 13:02
  • `exit` exits the whole script; again, if you want to terminate the loop, the command which does that is `break`. – tripleee Nov 19 '21 at 13:03
  • Sure I will give it a try. Thanks! – Asad Javed Nov 19 '21 at 13:21
  • Your code needs to be indentated. Or, you could use PasteBin. – Victor Leal Nov 19 '21 at 14:50
  • What needs to be indented? I feel It is properly indented except "EOF1". It gives me an end of file error if I indent it. Other than that the rest of the code looks perfectly indented. – Asad Javed Nov 19 '21 at 15:59