5

I'm sure this is a no-brainer when you're into shell programming. Unfortunately I'm not and I'm having a pretty hard time ...

I need to verify arguments passed to a shell script. I also want to store all parameters passed in an array as I need further separation later.

I have an argument "-o" which must be followed by either 0 or 1. Thus, I want to check if the following argument is valid. Here's what I tried:

# Loop over all arguments
for i in "$@"
do
    # Check if there is a "-" as first character,
    # if so: it's a parameter
    str="$i"
    minus=${str:0:1}

    # Special case: -o is followed by 0 or 1
    # this parameter needs to be added, too
    if [ "$str" == "-o" ]
    then
        newIdx=`echo $((i+1))`   # <-- problem here: how can I access the script param by a generated index?
        par="$($newIdx)"

        if [[ "$par" != "0" || "$par" != "1" ]]
        then
            echo "script error: The -o parameter needs to be followed by 0 or 1"
            exit -1
        fi
        paramIndex=$((paramIndex+1))

    elif [ "$minus" == "-" ]
    then
        myArray[$paramIndex]="$i"
        paramIndex=$((paramIndex+1))
    fi
done

I tried various things but it didn't work ... Would be grateful if someone could shed light on this!

Thanks

guitarflow
  • 2,930
  • 25
  • 38

2 Answers2

11

In bash, you can use indirect parameter expansion to access an arbitrary positional parameter.

$ set a b c
$ paramIndex=2
$ echo $2
b
$ echo ${!paramIndex}
b
chepner
  • 497,756
  • 71
  • 530
  • 681
1

There is no method to access next argument in for.

  1. How about to rewriting your script to use getopt?

  2. If you don't like getopt, try to rewrite your script using shift:


while [ -n "$1" ]
do
  str="$1"
  minus=${str:0:1}
  if [ "$str" == "-o" ]
  then
    shift
    par="$1"
#  ...
  elif [ "$minus" == "-" ]
  then
    # append element into array
    myArray[${#myArray[@]}]="$str"
  fi

  shift
done
Community
  • 1
  • 1
loentar
  • 5,111
  • 1
  • 24
  • 25
  • Thanks! I'll look into it in a minute. What confuses me: I can access each argument using $1, $2..., but it seems I can't do $parNum when parNum is a simple variable somewhere in the shell script. Is that right? – guitarflow Jun 04 '13 at 12:01
  • 1
    I don't know any method to access argument value by index that is stored in variable. But you can copy arguments into some variable and access it values as usual: `i=2; args=("$@"); echo "${args[$i]}"` – loentar Jun 04 '13 at 12:50
  • I second the recommendation to use either `getopts` (the `bash` built-in) or `getopt` (the external program). – chepner Jun 04 '13 at 12:58
  • @loentar: And thanks for the "append to array" trick. Just using it ;-) – guitarflow Jun 04 '13 at 13:51
  • 2
    @guitarflow: There's an easier way to append to an array: `myArray+=("$str")` -- be sure to include the parentheses, or it'll append to the first element rather than adding a new element to the array. – Gordon Davisson Jun 04 '13 at 16:02
  • Use `=`, not `==`, in `test` comparisons; only the former operator is POSIX-specified, so the latter will break if the OP uses practices they learned here when writing code for `/bin/sh`. See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html – Charles Duffy Mar 04 '18 at 15:50