title: How to use mutually exclusive flags in your shell and add an optional argument flag ( stuck with getopts)
body: <p>I am using a standard getopts logic. But I want to how I can make the options I offer- mutually exclusive. 
  e.g.        </p>
  
  <pre><code>shell.sh -a SID 
                                &lt;accepted&gt;
  shell.sh -b SID
                                &lt;accepted&gt;
  shell.sh -ab SID 
                 Message- using ab together is the same as running shell.sh     without   any   options supplying  just SID . Help usage &lt; ya da ya &gt; 
  shell.sh 
                  Please enter SID at the minimum. Usage &lt; ya da ya &gt;
  shell.sh SID
                 &lt;accepted&gt;
  </code></pre>
  
  <p>I am trying to develop this logic using something like below </p>
  
  <pre><code>while getopts ":a:b:" opt; do
    case $opt in
    a ) SID="$OPTARG";;
        set var=1
    b ) SID="$OPTARG";;
        set var=2
  
   \?) echo "Invalid option: -"$OPTARG"" &gt;&amp;2
          exit 1;;
    ) echo "Option -"$OPTARG" requires an argument." &gt;&amp;2
          exit 1;;
    esac
  done
  
  If  (( val == 1 ))  then ; # option a is invoked SID supplied 
  &lt;stuff&gt;
  elif  (( val == 2 )) then ; # option b is invoked SID supplied 
  
  &lt;stuff&gt;
  
  else # SID supplied but neither a or b is invoked 
  &lt;stuff&gt;
  fi
  </code></pre>
  
  <p>How do enforce  mutually exclusive flags. I a sure there are more acrobat ways to do it. I think I am missing something  commonsense here - and trying to figure that out .
  Thx </p>
  
  <pre><code>$ more opt.ksh
  die () {
      echo "ERROR: $*. Aborting." &gt;&amp;2
      return  1
  }
  
  var=
  while getopts ":a:b:" opt; do
    case $opt in
        a ) SID="$OPTARG"
            [ "$var" = 2 ] &amp;&amp; die "Cannot specify option a after specifying option b"
            [ "$OPTARG" = b ] &amp;&amp; die "Do not specify b as a value for option a"
            var=1
            ;;
        b ) SID="$OPTARG"
            [ "$var" = 1 ] &amp;&amp; die "Cannot specify option b after specifying option a"
            [ "$OPTARG" = a ] &amp;&amp; die "Do not specify a as a value for option b"
            var=2
            ;;
        :)  die "Must supply an argument to $OPTARG"
            ;;
        \?) die "Invalid option: -$OPTARG. Abort"
            ;;
    esac
  done
  shift $(($OPTIND - 1))
  [ "$SID" ] || SID=$1
  [ "$SID" ] || die "You must, at the minimum, supply SID"
  </code></pre>
  
  <p>I am using ksh </p>
  
  <pre><code>$ ps -p $$
    PID TTY          TIME CMD
   1261 pts/45   00:00:00 ksh
  </code></pre>
  
  <p>1st time  I run it .</p>
  
  <pre><code>$ . opt.ksh -a 123 -b 123  # c0
  ERROR: Cannot specify option b after specifying option a. Aborting.
  -bash: /home/d1ecom1/gin1: No such file or directory
  
  
  $ . opt.ksh -ab 123  # c1 should reject "cant use a and b togather. try with a or b"
  -nologin: .[25]: shift: 4: bad number
  $ . opt.ksh -a -b  # c2  same as c1's message
  $ . opt.ksh -a -b 123 # c3 same as c1
  
  $ . opt.ksh -a -b 123  # c5 
  $ . opt.ksh -ab 123    # c6
  $ . opt.ksh -a 123 -b 123  # c7
  </code></pre>
  
  <p>All above cases  C0:C7 should reject.  Notice C0 and C7 are the same. Yet inspite of this C0 gives the expected error and C7 will not give any  error ? strange </p>
  
  <p>only ones to work should be </p>
  
  <pre><code>. opt.ksh -a 123
  . opt.ksh -b 123
  . opt.ksh  123
  </code></pre>
  
  <p>@hvd :TYSM  for your reply.
  I would like to add an additonal flag -p that will give a "path override" option.
  so maybe we have to extend getopt to take parameters like this </p>
  
  <pre><code>    die () {
      echo "ERROR: $*. Aborting." &gt;&amp;2
      exit 1
  }
  
  var=
  opta=false
  optb=false
  while getopts ":ab:p" opt; do
    case $opt in
        a ) $optb &amp;&amp; die "Cannot specify option a after specifying option b"
            opta=true
            ;;
        b ) $opta &amp;&amp; die "Cannot specify option b after specifying option a"
            optb=true
            ;;
        p )  [ -d "$mypath" ] &amp;&amp; die "path is invalid"
  
            ;;
  
        \?) die "Invalid option: -$OPTARG. Abort"
            ;;
    esac
  done
  shift $(($OPTIND - 1))
  test $# -eq 0 &amp;&amp; die "You must supply SID"
  test $# -eq 1 || die "Too many command-line arguments"
  # SID=$1
  </code></pre>
  
  <p>The above was the old approach. Now I have 2 Input parameters. One is the SID and the other is the path. Is it as simple as the above or do I need to add more checks to prevent other unwanted combinations.  The question I guess I am trying to aim at is , what more provisions would need to be made to allow this -p parameter which is an optiona override parameter. - p can co-exist with any parameter above but then I guess one requirement is that it should be immediately following the -p flag
  so this should not allow - because its not clear .</p>
  
  <pre><code>shell.sh -b -p 123 /home/yadaya
  </code></pre>
  
  <p>Thanks again </p>