2

I would like to make a script where you can give a couple of parameters with it:

while getopts ":a:b:c:" opt; do
  case $opt in
    a)
      echo "-a was triggered
      ;;
    b)
      echo "-b was triggered
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

The code I have now works but the problem I have is that I want to give another function/echo if it combines.

Example: When I do: .MyScript -ab than it should give another function that what is defined in "a" or in "b"

so a bit like:

ab) -> Script -a -b or Script -ab 
 echo "-ab was triggered"

What is the best solution to do this? Any ideas, your free to post!

user2252399
  • 153
  • 1
  • 1
  • 8

2 Answers2

1
while getopts ":a:b:c:" opt; do
  case $opt in
    a)
      echo "-a was triggered"
      a_val=$OPTARG
      ;;
    b)
      echo "-b was triggered"
      b_val=$OPTARG
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done
if [[ -n $a_val ]]; then do something with "$a_val"; fi
if [[ -n $b_val ]]; then do something with "$b_val"; fi

The only situation this may cause confusion is if the user passes -a "" -- one workaround is:

a=false
b=false
while getopts ":a:b:c:" opt; do
  case $opt in
    a) echo "-a was triggered"; a_val=$OPTARG; a=true ;;
    b) echo "-b was triggered"; b_val=$OPTARG; b=true ;;
  esac
done
if $a; then do something with "$a_val"; fi
if $b; then do something with "$b_val"; fi

Here, there are no brackets: if $a; then ... because I'm invoking the command "true" or "false" and acting on that exit status.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
1

UPDATED

You can use the getopt(1) linux utility. This is not a internal function, but this can handle long arguments.

Try this:

declare -A OPTARG
GetOpt() {
  local prog="${BASH_SOURCE[0]}"
  [ $# -eq 0 ] && echo "$prog: Bad call of GetOpts">&2 && exit 1
  local longopt="$1"
  shift

  local tmp
  tmp=$(getopt -n"$prog" -a -l "$longopt" -- '' "$@") || exit
  eval "tmp=($tmp)"

  local i
  for((i=0;i<${#tmp[*]};++i)){
    key=${tmp[i]#--}
    [ -z "$key" ] && break
    if [[ "${tmp[i+1]}" =~ ^-- ]]; then OPTARG[$key]=1
    else OPTARG[$key]="${tmp[++i]}"
    fi
  }
  for((j=0;++i<${#tmp[*]};++j)){ OPTFILE[j]=${tmp[i]};}
}

GetOpt "a b ab file:" "$@"

[ "${OPTARG[a]}" -a "${OPTARG[b]}" ] && OPTARG[ab]=1 && unset OPTARG[a] OPTARG[b]

[ "${OPTARG[a]}" ] && echo Do a
[ "${OPTARG[b]}" ] && echo Do b
[ "${OPTARG[ab]}" ] && echo Do ab

The defined GetOpt function will place the parsed command line argument with the checked long options to the associative array called OPTARG. If there is an error it will fail informing about the problem.

With getopt's -a option you can use -ab or --ab format. Keep in mind that if You have del defined, then the -d option (if -d is not specified) will expand to --del.

If You specify an arg with additional option it can contain spaces. E.g. if -l file: defined in getopt then it can be used as ./test --file="q w". ${OPTARG[file]} will be q w.

The OPTFILE array contains the optional arguments (args given after --).

TrueY
  • 7,360
  • 1
  • 41
  • 46
  • This works good but is it possible to refer to --ab if I want to run my script like this: . MyScript -a -b ? – user2252399 Jun 03 '13 at 11:14
  • @user2252399: Sure! In the `case` `-a` check `$2` whether it is `-b`. If it is, then do what You want for `--ab` (and do a shift to remove `-b` from command line).. – TrueY Jun 03 '13 at 11:17
  • @user2252399: Or You can check after the `while-loop` that both `-a` and `-b` options is set (see env.var `a` and `b`). It yes, set the variable `ab` and clear `a` and `b`. – TrueY Jun 03 '13 at 11:41
  • @user2252399: I reduced the code a little bit and I added the handling of both `-a` and `-b`. Pls check! – TrueY Jun 03 '13 at 12:02
  • @user2252399: More complete version. Does not modifies command line arguments, stops if bad args were passed and handles opt.args with spaces. – TrueY Jun 03 '13 at 13:27