0

I am still "baking" my shell with these features so my question may not sound like "totally ready" ..its more of a "whats the best way to design this" as against something like "I ran into this error or this wont work..now what do I do ", so bear with me pl. while I explain
I am thinking of a shell program which can be run in 2 modes

  • Standard Mode is a bunch of positional parameters
    e.g. myprogram date1 date2 date3 date4 # can go on indefinitely
  • Named Parameter mode
    myprogram -r date1 # Just 1 date para allowed

They are of course mutually exclusive myprogram date1 date2 date3 date4 is ok
myprogram -r date1 date2 date3 date4 is not because 1 only parameter is expected with -r

I am aware of getopts offering a named parameter feature that can shift through a bunch of options.
I have the standard mode ready & working and would like to "add" to the code to get the named parameter mode
In standard mode my code is patterned like

for args
do
stuff that I want done here 
shift
done

So here is what I am thinking for the named parameter mode logic
(When I use getopts and more that 1 positional parameters is used It should quit. )
With getopts allowing just 1 parameter, I am thinking of some like this

while getopts "r:"  opt; 
do
case statement of getopts 
<stuff I want to do >
esac 
done


and for limiting positional paras to just 1 I should have something like this ?
[ "$#" -eq 2 ] || die " more than 1 para not expected here"
the 2 is because while i am in the while loop above , -r is the 1st pos. para and 1 para is the variable one that gets in there. I have to do the checking within the loop because , I want it to fall through without anything being done if -r option is not used , in which case I can have as many pos parameters as I need
So how do I cook this best- is what I am trying to understand. Put the getopts code 1st and then follow through with the positional parameter code ? Sorry if I could be too specific in my question.

user1874594
  • 2,277
  • 1
  • 25
  • 49
  • Is there a difference between `myprogram date1` and `myprogram -r date1`? If not, don't clutter your interface with unnecessary options. – chepner Feb 07 '16 at 17:23
  • Yes there is `myprogram date1` gets just the 1st level dates and `myprogram -r date` will get the data recursively and that is why the recursive option needs just 1 date parameter not a bunch of em. Thanks for looking ! – user1874594 Feb 07 '16 at 17:27

2 Answers2

2

I don't always use getopts, but when I do, it looks something like this:

...

#Defaults
Verbose=false
ropt=false

# Options
while getopts vr: opt; do
  case "$opt" in
    v)  Verbose=true; vopt="-v" ;;
    r)  ropt=true; rarg="$OPTARG" ;;
    *)  usage; exit 1 ;;
  esac
done
shift $((OPTIND - 1))

if $ropt && [ $# -gt 0 ]; then
  $Verbose && echo "Too many arguments. Bye." >&2
  exit 1
elif $ropt; then
  args=( "$rarg" )
else
  args=( "$@" )
fi

# then...
for thing in "$args"; do
  ... something with $thing ...
done

The first condition after the getopts loop controls whether you're running in multi-argument or single argument (-r) mode. The subsequent elses populate the $args array, which you can then do whatever you like with later.

ghoti
  • 45,319
  • 8
  • 65
  • 104
1

I use getopts instead of getopt but I assume logic is the same. Loop through the named options and then once you're done, if you haven't set your option, just use the remaining options.

ARGS=$(getopt --options=r: --name="$0" -- "$@");
if [ $? -ne 0 ]; then
    echo_usage
    exit 1
fi

eval set -- "$ARGS";

while true; do
    case $1 in
        -r)
            shift
            date1=$1
        ;;
done

if [ -z "$date1" -a ! -z "$1" ]; then
    date1=$1
fi
miken32
  • 42,008
  • 16
  • 111
  • 154