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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.