Read Strings in as options to switches

I have a script using getops with -a -t -l as potential switches, based on the switches used, it will set the respective variable value which will cause the routine/function to run. I need to also pass a string with the switch that will get parsed by the function.

example
./myscript -a apples,oranges,pears -t ham,pastrami,bologna

while getops atl OPTION
do
case $OPTION in
a) AVAR=ACTIVE ;;
t) TVAR=ACTIVE ;;
esac
done

if [ $AVAR ]
then
read in string "apples,oranges,pears"
etc...

if [$TVAR]
then
read in string "ham,pastrami,bologna"

I need help to pass the strings that follow the switches in to the blocks that apply to those switches. I don't want an interactive script, I need to pass everything as args.

I haven't seen that getopt actually makes shell code any simpler...

while [ "$#" -gt 0 ]
do
        case "$1" in
        -a)   AVAR=ACTIVE
                ASTR=$2
                shift
                ;;
        -t) TVAR=ACTIVE
              TSTR=$2
              shift
        --)  shift ; break ;;
        -*)  echo "Unknown option" >&2
              exit 1
              ;;
        *) break ;;
        esac

        shift
done


echo "AVAR $AVAR ASTR $ASTR"
echo "TVAR $TVAR TSTR $TSTR"
$ ./script.sh -a abcd,efg,hij -t def,gh,jkl
1 Like

That is a great idea, thanks. There is a chance that both switches will be used, each with a string passed to them, and that they can be passed out of order. I can use this logic, but I will have to account for a being $3 and t being $1 or whatever, but it will still work. I also agree, getops seems to be almost not worth using, it's often as simple to just write some logic to handle the args.

Actually, this already accounts for it. See the shift statements. They remove the first argument and move everything down. That's why I can just check $1 every loop.

i.e. if $1=a, $2=b, $3=c, after you do shift, you get $1=b, $2=c.

There's an extra shift in the flags that take arguments to keep the loop in sync.

1 Like

I see now, thanks!

Good one, but if you want to give getopts another try:

# cat myscript 
#!/usr/bin/ksh

while getopts "a:t:" opt
do
   case "${opt}" in 
    a) AVAR=ACTIVE 
       string_avar="${OPTARG}" ;;
    t) TVAR=ACTIVE 
       string_tvar="${OPTARG}" ;;
   esac
done

if [ "${AVAR}." != "." ] 
then
   echo "string_avar: ${string_avar}"
fi

if [ "${TVAR}." != "." ] 
then
   echo "string_tvar: ${string_tvar}"
fi
# ./myscript -a apples,oranges,pears -t ham,pastrami,bologna
string_avar: apples,oranges,pears
string_tvar: ham,pastrami,bologna

Hi.

With some work, one can use features of ksh93s+ getopts to accept many variations, and even to produce a man page for the script automatically. See Help on getopts in ksh , post 7 for examples.

Best wishes ... cheers, drl (92)

If you have some options that take option arguments and some that don't, you'll find that getopts gives you lots of capabilities that the type of script provided in message #2 in this thread does not provide. These capabilities allow shell scripts to parse options like the standard utilities defined by the POSIX standards and the Single UNIX Specifications. (Multiple options can be grouped after a single "-", option arguments can be separate from the option flag or combined into a single operand, etc.)

For a better example of what you can do with getopts, try something like:

#!/bin/ksh
AVAR="Default avar value"
BF=
CF=
TVAR="Default tvar value"
while getopts 'a:bct:' x
do      case "$x" in
        (a)     AVAR="$OPTARG";;
        (b)     BF=1;;
        (c)     CF=1;;
        (t)     TVAR="$OPTARG";;
        (?)     echo "Usage: $0 [-bc] [-a AVAR_string] [-t TVAR_string] [file...]"
                exit 1
        esac
done
shift $((OPTIND - 1))
echo "AVAR is set to $AVAR"
if [ "$BF" == 1 ]
then    echo "Option b present"
fi
if [ "$CF" == 1 ]
then    echo "Option c present"
fi
echo "TVAR is set to $TVAR"
echo "$# file operand(s) present:"
while [ $# -gt 0 ]
do      printf "\t%s\n" $1
        shift
done
exit

Save it in a file (e.g., tester ). Change the /bin/ksh in the 1st line to an absolute pathname of a standards conforming shell on your system. I use the Korn shell, but this script will work with bash and several other shells. (However, it won't work with csh or similar shells like tcsh.) Make the script executable by running the command:

chmod +x tester

and try running it with several test cases. For example:

./tester -a "a value" -c  -b
./tester -baastring -t tstring file1 file2
./tester -d file
2 Likes

Top class explanation Don