4
#!/bin/bash

priority=false
it=0
dir=/

while getopts  "p:i" option
do
  case $option in
         i) it=$OPTARG;;
         p) priority=true;;
   esac
done

if [[ ${@:$OPTIND} != "" ]]
then
    dir=${@:$OPTIND}
fi
echo $priority $it $dir

If I execute it I get 2 testDir for $dir and 0 for $it, instead of just testDir for $dir and 2 for $it. How can I get the expected behavior?

./test.sh -pi 2 testDir
true 0 2 testDir
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
simpatico
  • 10,709
  • 20
  • 81
  • 126
  • If you use -p 2 -i testDir do you get the behavior you want? – sdolgy Jul 16 '11 at 05:36
  • http://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash – Eric Fortis Jul 16 '11 at 06:03
  • Run `bash -x ./test.sh` to see what your script is doing. The `if` block looks really weird: it means if there is a non-empty non-option argument, then set `dir` to the result of performing pathname expansion and word splitting on the non-option arguments and concatenating them with spaces. (Complicated, eh?) I suspect you meant `if [[ ${!OPTIND} != "" ]]; then dir=${!OPTIND}; fi`. The usual method is even simpler: run `shift $OPTIND` after parsing the option, so that the non-option arguments are `$1`, `$2` and so on, thus `if [[ -n $1 ]]; then dir=$1; fi`. – Gilles 'SO- stop being evil' Jul 16 '11 at 09:05

2 Answers2

2

I would write this:

#!/bin/bash

priority=false
it=0

while getopts ":hpi:" opt; do
    case "$opt" in
        h) echo "usage: $0 ...."; exit 0 ;;
        p) priority=true ;;
        i) it="$OPTARG" ;;
        *) echo "error: invalid option -$OPTARG"; exit 1 ;;
    esac
done

shift $(( OPTIND - 1 ))

dir="${1:-/}"

echo "priority=$priority"
echo "it=$it"
echo "dir=$dir"
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
1

You seem to have the optstring parameter to getopts wrong. You have p:i, while what you want is pi:, so that the -i switch takes the argument.

Jukka Matilainen
  • 9,608
  • 1
  • 25
  • 19