tags:

views:

51

answers:

3

I have to use a Unix script to pass arguments:

./Script.sh -c "abc" -d "def" -k "abc -d -c"

where the argument for:

  • -c = "abc"
  • -d = "def"
  • -k = "abc -d -c"

How can I handle options in a Uunix shell script?

A: 

There is a command getopts, and a program getopt, though I'm of the opinion that by the time you need to handle arguments, you've outgrown shell scripting.

I'm not actually sure how getopts work, having never actually used it; but here, and check your shell's docs.

getopt splits your arguments into flags -- rest as far as I can tell.

sreservoir
Using `getopt` is prone to problems with spaces in the arguments - basically, it does not handle them accurately. The built-in `getopts` does handle spaces in arguments correctly.
Jonathan Leffler
+1  A: 

Here is some option handling using getopts:

#   -F          Final version (do not append date to version)
#   -s suffix   Add '-suffix' after version number
#   -V          Print version and exit
#   -h          Print help and exit
#   -j jdcfile  JDC file for project - required
#   -q          Quiet operation
#   -v          Verbose operation

arg0=$(basename $0 .sh)

usage()
{
    echo "Usage: $arg0 [-hqvFV] [-s suffix] -j jdcfile file.msd" 1>&2
    exit 1
}

error()
{
    echo "$0: $*" 1>&2
    exit 1
}

Fflag=
suffix=
jdcfile=
qflag=
vflag=no
while getopts FVhj:qs:v opt
do
    case "$opt" in
    (F) Fflag="-F";;
    (V) echo "Version information";;
    (h) echo "Help information";;
    (j) jdcfile="$OPTARG";;
    (q) qflag="-q";;
    (s) suffix="$OPTARG";;
    (v) vflag=yes;;
    (*) usage;;
    esac
done

shift $(($OPTIND - 1))

case $# in
(1) : OK;;
(*) usage;;
esac

if [ -z "$jdcfile" ]
then error "you did not specify which jdcfile to use (-j option)"
fi

The script then continues and does its task based on the options it was given. The shift removes the 'consumed' options, leaving just the file name arguments.

Jonathan Leffler
#!/bin/bash args=`getopt c:m:p $*` if [ $? != 0 -o $# == 0 ] then echo 'Usage: -c <current-dir> -m <my dir> -p <argument>' exit 1 fi set -- $args for i do case "$i" in -c) shift;CURRDIR=$1;shift;shift ;; -m) MYDIR=$1;shift;; -p) ARGVAL=$OPTARG;; esac done echo "CURRDIR = $CURRDIR" echo "MYDIR = $MYDIR" echo "ARGVAL = $ARGVAL"
A: 

Can someone fix this issue...

#!/bin/bash

args=`getopt c:m:p $*`

if [ $? != 0  -o $# == 0 ]
then
  echo 'Usage: -c <current-dir> -m <my dir> -p <argument>'
  exit 1
fi

set -- $args

for i
do
 case "$i" in
         -c) shift;CURRDIR=$1;shift;shift ;;
         -m) MYDIR=$1;shift;;
         -p) ARGVAL=$OPTARG;;
   esac
done

echo "CURRDIR = $CURRDIR"
echo "MYDIR = $MYDIR"
echo "ARGVAL = $ARGVAL"

Can someone fix this issue. i am not geting value in ARGVAL, if i give option something like

./1.sh -c "def" -m "ref" -p "ref -k ref"

output -c = "def"
-m ="ref"
-p ="ref -k ref

"