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

7
  • Show us your command line. Commented Aug 19, 2014 at 18:42
  • bash program -var1 hello -var2 world Commented Aug 19, 2014 at 18:43
  • stackoverflow.com/q/192249 Commented Aug 19, 2014 at 18:44
  • 1
    What are -fef and -scripts then? Also, $x doesn't seem necessary, especially since it is always just $i+1. Commented Aug 19, 2014 at 18:45
  • I have previously looked at that code, and I understand that is an alternate way to do it. I am still unsure why the above code does not work, which is why I asked the question. Commented Aug 19, 2014 at 18:48

3 Answers 3

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
Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.