ksh processing options and parameters

I have a requirement where I need to process both options and parameters.

command line call

ie xxx.ksh -sid TEST1 -search_str LOCKED  user1 user2 .....
 

I am using the following peice of code but I am usure how I can loop through all my parameters user1, user2, ... Note at the minium there were
be at least "user1"

Can somebody provide and example.

while [ $# -gt 0 ]
do
     case $1 in
     -+([sS]*(id|ID)))
          shift
          export ORACLE_SID=$1
          ;;
     -+([sS]*(earch_string|EARCH_STRING)))
          shift
          export SEARCH_STRING=$1
          ;;
       *) shift ;;
   esac
done

 

Thanks to all who answer

---------- Post updated at 02:50 PM ---------- Previous update was at 11:29 AM ----------

My solutuon. Its not fancy but appears to work. Any elegant solutuons are more than welcome

 
#!/bin/ksh
 
let i=0
set -A parameters
typeset -L1 first_char_in_last_arg

while [ $# -gt 0 ]
do
     case $1 in
     -+([sS]*(id|ID)))
          shift
          export ORACLE_SID=$1
          shift
          ;;
     -+([sS]*(earch_string|EARCH_STRING)))
          shift
          export SEARCH_STRING=$1
          shift
          ;;
       *)
         first_char_in_last_arg="$1"
         if [ "$first_char_in_last_arg" != "-" ]
         then
            parameters[$i]="$1"
            ((i=i+1))
         fi
         shift ;;
   esac
done
for i in ${parameters[@]}
do
   echo $i
done

 

Not fancy perhaps, but far from being bad also, I just had a little moment to spare and looked at your script and I like it...

I'm not sure where to start here, but there are several problems. By convention, UNIX utility options that are introduced with a single minus sign should have single character option names. Long options (options with option names that are more than one character) should be introduced by two minus signs, (e.g., --version ). Option names should be case sensitive. (It isn't unusual for some option arguments to be case insensitive, but not the option names themselves.) When a utility uses a single character option that uses an option argument, it should allow that option argument to be part of the same command line argument as the option itself. (This means, for example, that the width of an output line to be produced by the fold utility can be specified either as:

fold -w72 file
    or as:
fold -w 72 file

and get exactly the same results.) However, this does not apply to long option names. A long option option argument must be a separate argument from the argument that contains the long option name.

The standards only specify the behavior of single character options and provide the getopts utility to parse command line options given to shell scripts, but most implementations provide implementation-specific extensions to parse command line options when the utility is parsing long options. The getopts(1) man page on your system will probably either describe how it has been extended to parse long options or the SEE ALSO section will point you to another utility that can be used to parse long options on that system.

There is a reasonable example on the POSIX getopts man page linked to above showing how to parse commands lines similar to what you're trying to do as long as you only use single character option names. That example would be worth examining even if you're going to use long options.

If your ie script starts with the code you included in the 1st message in this thread, a recent Korn shell is used to evaluate it (I'm guessing since you specified xxx.ksh as an argument to this script), and you invoke it with the command:

ie xxx.ksh -sid TEST1 -search_str LOCKED  user1 user2 .....

a case like:

     -+([sS]*(id|ID)))
          shift
          export ORACLE_SID=$1
          ;;

will not only match -s, -S, -sid and -SID, it will also match -SsSssSS and -SidIDssIDid and an infinite number of other combinations; and the following command line argument will not only be assigned as the value the ORACLE_SID exported environment variable, it will also processed as another command line argument the next time through the loop. I would have expected that you intended something like:

     -([sS]?(id|ID)))
          shift
          export ORACLE_SID=$1
          shift
          ;;

which would match -s, -S, -sid, -Sid, -sID, and -SID; or:

     -([sS]?([iI][dD])))
          shift
          export ORACLE_SID=$1
          shift
          ;;

which would match -s, -S, -sid, -siD, -sId, -sID, -Sid, -SiD, -SId, and -SID. (NOTE that I do not suggest nor condone either of these possibe replacements since I think you should follow standard utility command line parsing conventions; I'm just pointing out that the Korn shell pattern matching expressions you're using don't seem to match the description of what I think you were trying to do.)

Although many Linux utilities allow options to be intermixed with operands, the standards do not suggest that any new utilities do that. Options should come before operands and option processing should be terminated by the first non-option arugment that does not start with a minus sign or can be terminated by an operand that is exactly two minus signs. (There are a few utilities in the standard that allow intermixed options and operands for compatibility with historical versions of those utiiities. And there are occasional cases where it makes sense for new utilities when options change for different sets of operands, but, generally, this should be avoided.)

The code you provided not only allows intermixed options and operands, it also processes option arguments both as option arguments and as possible options or operands. And all operands are effectively ignored and made unavailable to the rest of your script after the options have been parsed.

I hope this gives you a few things to think about as you write specifications for utility behavior and as you write command line parsing code. Good luck.

-------------------

Oops. I see that you updated your script while I was composing my response. Your updated script is much better (it no longer just discards operands and it no longer double processes option arguments), but the other comments still apply.