Search code examples
bashshellshgetoptgetopts

How can I make an option require another option?


I'm making a script that accepts options and two of them are -s and -e. The -s requires a start date and the -e requires and end date, but I want to make it so one can't be used without the other. In other words, if I use the -s option the -e option is also required and vice-versa.

Here's my code so far

#!/bin/bash

gflag=false
uflag=false
sflag=false
eflag=false
rflag=false
nflag=false
tflag=false

while getopts g:u:s:e:rnt opt; do
  case "$opt" in
    g)
      gflag=true
      groupParam=$OPTARG
      echo "-g was triggered, Parameter: $OPTARG" >&2
      ;;
    u)
      uflag=true
      userParam=$OPTARG
      echo "-u was triggered, Parameter: $OPTARG" >&2
      ;;
    s)
      sflag=true
      startParam=$OPTARG
      echo "-s was triggered, Parameter: $OPTARG" >&2
      ;;
    e)
      eflag=true
      endParam=$OPTARG
      echo "-e was triggered, Parameter: $OPTARG" >&2
      ;;
    r)
      rflag=true
      echo "-r was triggered" >&2
      ;;
    n)
      nflag=true
      echo "-n was triggered" >&2
      ;;
    t)
      tflag=true
      echo "-t was triggered" >&2
      ;;
  esac
done

How can I change my code to be able to do this?


Solution

  • After you parse all the options (after the while loop), you can do

    if ($sflag && ! $eflag) || (! $sflag && $eflag); then
        echo "Cannot specify -s without -e or vice versa" >&2
        exit 1
    fi
    

    I'm taking advantage of the fact that true and false are builtin commands that return the expected status.

    Can also write this without using subshells, but it's a little noisier:

    if { $sflag && ! $eflag; } || { ! $sflag && $eflag; }; then