0

I'm trying to read command line arguments through a bash scripts and am having difficulties getting desired results. I want to read in two parameters, one after -var1 and one after var2.

I am passing in these arguments

-var1 hello -var2 world

args=("$@")
x="0"
for (( i=0;i<$#; i++ ))
do
  x=$(($x + 1))
  echo " $i $x "
  if [[ ${args[${i}]} == "-var1" ]] ; then
    if [ $# > $x ] ; then
        var1="${args[${i+1}]}"
    fi
  fi
  echo $i
  if [[ ${args[${i}]} == "-var2" ]] ; then
    if [ $# > $x ] ; then
        var2="${args[${i+1}]}"
    fi
  fi
done

It sets both variables, var1 and var2, equal to hello, rather than var1="hello" and var2="world". Any thoughts? Thanks in advance

jaypal singh
  • 74,723
  • 23
  • 102
  • 147

3 Answers3

2

Try doing it this way instead:

#!/bin/bash

while [[ $# -gt 0 ]]; do
    case "$1" in
    -var1)
         var1=$2
         shift
         ;;
    -var2)
         var2=$2
         shift
         ;;
    *)
         echo "Invalid argument: $1"
         exit 1
    esac
    shift
done

if [[ -z $var1 ]]; then
    echo "Var1 was not specified."
    exit 1
fi

if [[ -z $var2 ]]; then
    echo "Var2 was not specified."
    exit 1
fi

... do something with var1 and var2
konsolebox
  • 72,135
  • 12
  • 99
  • 105
1

I agree with konsolebox.

Your code is suffering from excessive variable bracing. ${i+1} will not actually perform the addition. The expression within [] in an array expansion is evaluated as an arithmetic expression. Try this:

args=("$@")
for (( i=0; i<$#; i++ ))
do
    [[ ${args[i]} == "-var1" ]] && var1=${args[++i]}
    [[ ${args[i]} == "-var2" ]] && var2=${args[++i]}
done
echo "var1='$var1'"
echo "var2='$var2'"

output

var1='hello'
var2='world'

We could get more dynamic about it:

args=("$@")
for (( i=0; i<$#; i++ )); do
    [[ ${args[i]} == -* ]] && declare ${args[i]#-}=${args[++i]}
done

or even

while (( $# > 0 )); do
    [[ $1 == -* ]] && { declare ${1#-}=$2; shift; }
    shift
done
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
0

Use getopts ->

while getopts "a:b:" flag
do
   case "$flag" in
   a) echo "var1=$OPTARG"
   ;;
   b) echo "var2=$OPTARG"
   ;;
   *) echo "Incorrect Usage"
   ;;
   esac
done

Then run it as -a "hello" -b "world"

dganesh2002
  • 1,917
  • 1
  • 26
  • 29