Passing Arguments to Shell Script

Nik picture Nik · Oct 26, 2013 · Viewed 9k times · Source

Very simple question may be but not able to get this working....essentially i have a XML file which is internally allows me to pass few arguments to a external program in my case i chose shell script due to unavoidable reasons.

Now it is working for the most part but i hit issue, essentially i am passing 12 arguments from XML to shell script -- passing and consuming arguments in shell worked fine till 9th argument when i hit 10th 11th 12th argument they are concatenating ARG1 with 0 for 10th argument, ARG1 with 1 for 11th argument and Arg1 with 2 for 12th argument.

ARG1=$1    # Name    
ARG2=$2    # Text     
ARG3=$3    # Model    
ARG4=$4    # Network Address    
ARG5=$5    # Type    
ARG6=$6    # Landscape    
ARG7=$7    # Cause    
ARG8=$8    # Troubleshooter    
ARG9=$9    # Originiating Event    
ARGX=$10   # Status    
ARGY="$11" # Customer    
ARGZ="$12" # Category

so essentially value of ARG10 is ARG1 and 0 for ex lets say you pass ARG1 as "text" and ARG10 as "New" from XML file to shell script but when ARG10 is echoed out in shell script it echoes - "text0" instead of new.
I am very sure this is a silly thing i am doing need some help understanding where i am wrong in coding it.

Answer

Mark Reed picture Mark Reed · Oct 26, 2013

You need to use curly braces when you have more than one digit.

ARGX=${10}

etc. (Note that you don't need quotation marks around a parameter expansion that is the entire right side of an assignment statement.) Without the braces, $10 is interpreted as $1 followed by a literal 0.

You can also use braces for the single-digit arguments (as well as any other shell parameter names), just for consistency. But with double-digit argument numbers, they're a necessity.

Once you get to the point that you have that many parameters to something, though, it might be worth looking into some sort of explicit naming scheme. Perhaps you could use option syntax, with something like func -name "$name" -text "$text", etc. Then you could do something like this (assuming bash >= 4):

declare -A args=()
while (( $# )); do
  case "$1" in  -*) key="${1#-}";;
                 *) args[$key]="$1";;
  esac
  shift
done

# now the name is ${args[name]}, text is ${args[text]}, etc.