Home > other >  How to choose any number of elements through user input in bash?
How to choose any number of elements through user input in bash?

Time:11-05

I have created this script which currently is taking a list of arguments from command line but what I want to do is let the user pass any numerical value which would then start executing the loop for number of the times the user has asked. The script is run in the following way for example ./testing.sh launch 1 2 3 4 5 6 7 8. How can I make a user pass a numerical value like 8 which would then loop over the IPs instead of doing 1 2 3 4 5 6 7 8. Also is there a better way to deal with so many IPs that I have passed in the script like for example map them and read them from a file.

#!/bin/bash
#!/usr/bin/expect

ips=()
tarts=()

launch_tarts () {
    local tart=$1
    local ip=${ip[tart]}
    
    echo "    ----  Launching Tart $1  ----  "
        sshpass -p "tart123" ssh -Y -X -L 5900:$ip:5901 tarts@$ip <<EOF1
        export DISPLAY=:1
        gnome-terminal -e "bash -c \"pwd; cd /home/tarts; pwd; ./launch_tarts.sh exec bash\""
        exit
EOF1
}
    
kill_tarts () {
    local tart=$1
        local ip=${ip[tart]}

    echo "    ----  Killing Tart $1  ----   "
    sshpass -p "tart123"  ssh -tt -o StrictHostKeyChecking=no tarts@$ip <<EOF1
        . ./tartsenvironfile.8.1.1.0
        nohup yes | kill_tarts mcgdrv &
        nohup yes | kill_tarts server &
        pkill -f traf
        pkill -f terminal-server
        exit
EOF1
}

tarts_setup () {
    local tart=$1
        local ip=${ip[tart]}

    echo "    ----  Setting-Up Tart $1  ----   "
        sshpass -p "root12"  ssh -tt -o StrictHostKeyChecking=no root@$ip <<EOF1
        pwd
        nohup yes | /etc/rc.d/init.d/lifconfig 
        su tarts
        nohup yes | vncserver 
        sleep 10
        exit
    exit
EOF1
}

ip[1]=10.171.0.10
ip[2]=10.171.0.11
ip[3]=10.171.0.12
ip[4]=10.171.0.13
ip[5]=10.171.0.14
ip[6]=10.171.0.15
ip[7]=10.171.0.16
ip[8]=10.171.0.17
ip[9]=10.171.0.18
ip[10]=10.171.0.19
ip[11]=10.171.0.20
ip[12]=10.171.0.21
ip[13]=10.171.0.100
ip[14]=10.171.0.101
ip[15]=10.171.0.102
ip[16]=10.171.0.103
ip[17]=10.171.0.104
ip[18]=10.171.0.105
ip[19]=10.171.0.106
ip[20]=10.171.0.107

case $1 in
    kill) function=kill_tarts;;
    launch) function=launch_tarts;; 
    setup) function=tarts_setup;;
    *) exit 1;;
esac 

shift

for tart in "$@"; do
    ($function $tart) &
    ips =(${ip[tart]})
#   echo $ips
    tarts =(${tart[@]})
#   echo $tarts
done
wait

Can someone guide please?

CodePudding user response:

You want the seq command:

for x in $(seq 5); do
  echo $x
done

this will produce the output

1
2
3
4
5

Then just take the number of iterations you want as another parameter on the command line, and use that in place of the hard coded 5 in my example.

seq just generates a sequence of numbers. From the man page:

SYNOPSIS
seq [-w] [-f format] [-s string] [-t string] [first [incr]] last

DESCRIPTION
The seq utility prints a sequence of numbers, one per line >(default), from first (default 1), to near last as possible, in >increments of incr (default 1). When first is larger than last the >default incr is -1.

CodePudding user response:

  • Try changing the bottom loop to: for ((tart=1; tart<=$2; tart )), then use like: ./testing.sh launch 8.

  • You you can put multiple variable declarations on one line, so you could split the ip list in to two or three columns.

  • Or use mapfile: mapfile -t ip < ip-list. You will need to use tart - 1 for the array index though, like "${ip[tart-1]}", as the array will start at 0, not 1.

  • Related