user3663615
user3663615

Reputation: 41

Using positional arguments in a bash script

This is my script script.sh:

Numbr_Parms=$#
a=`expr $Numbr_Parms - 2`
while [ $a -le $Numbr_Parms ]
do
    if [ "$a" =  "3" ]
    then
       PARAMSTRING="-param $3"
    else
       PARAMSTRING="$PARAMSTRING -param $a"
    fi
    a=`expr $a + 1`
done
echo $PARAMSTRING

Running:

script.sh  username pass p1=v1 p2=v2 p3=v3

Expected output:

-param p1=v1 -param p2=v2 -param p3=v3

But i am getting: $PARAMSTRING as

-param p1=v1 -param 4 -param 5

Not sure what is the Issue with $4 and $5

Upvotes: 0

Views: 1103

Answers (3)

fedorqui
fedorqui

Reputation: 289765

In:

PARAMSTRING="$PARAMSTRING -param $a"

You want to append the parameter in the position a. However, $a just holds the number. So to access $1, $2, etc you have to use variable indirection:

PARAMSTRING="$PARAMSTRING -param ${!a}"

The full script can be reduced to a simple loop over the parameters, using $# as limit:

for ((i=3; i<=$#; i++)); do
        PARAMSTRING="$PARAMSTRING -param ${!i}"
done
echo "$PARAMSTRING"

Or, even better, you can use an array like chepner shows in his answer.

Upvotes: 0

user5076313
user5076313

Reputation:

The problem is in the below line.

PARAMSTRING="$PARAMSTRING -param $a"

In this the $a does not means the positional argument. It is a variable it have the 4, 5, like that only.

If you print that variable you will not get the positional argument. You get only 4, 5, 6 only.

So, you have to get the positional argument using that variable a.

Try the below step it will work as you expect.

Numbr_Parms=$#
a=`expr $Numbr_Parms - 2`
while [ $a -le $Numbr_Parms ]
do
    if [ "$a" =  "3" ]
    then
        PARAMSTRING="-param $3"
    else
        eval pos=\$$a    # This is the indirect reference to get the positional argument from variable a.
        PARAMSTRING="$PARAMSTRING -param $pos"
    fi
    a=`expr $a + 1`
done

echo $PARAMSTRING

Upvotes: 0

chepner
chepner

Reputation: 531225

If you want to skip the first two positional parameters, just use

for arg in "${@:3}"; do
    PARAMSTRING+="-param $arg "
done

The right way to build up a sequence of parameters, though, is to use an array, which will work even if one of the arguments itself contains whitespace.

for arg in "${@:3}"; do
    PARAMS+=(-param "$arg")
done

mycommand "${PARAMS[@]}"

Upvotes: 2

Related Questions