views:

31

answers:

4

In the middle of a scrip, I want to check if a given flag was passed on the command line. The following does what I want but seems ugly:

if echo $* | grep -e "--flag" -q
then
  echo ">>>> Running with flag"
else
  echo ">>>> Running without flag"
fi

Is there a better way?

Note: I explicitly don't want to list all the flags in a switch/getopt. (In this case any such things would become half or more of the full script. Also the bodies of the if just set a set of vars)

+1  A: 

You can use the getopt keyword in bash.

From http://aplawrence.com/Unix/getopts.html:

getopt

This is a standalone executable that has been around a long time. Older versions lack the ability to handle quoted arguments (foo a "this won't work" c) and the versions that can, do so clumsily. If you are running a recent Linux version, your "getopt" can do that; SCO OSR5, Mac OS X 10.2.6 and FreeBSD 4.4 has an older version that does not.

The simple use of "getopt" is shown in this mini-script:

#!/bin/bash
echo "Before getopt"
for i
do
  echo $i
done
args=`getopt abc:d $*`
set -- $args
echo "After getopt"
for i
do
  echo "-->$i"
done
WhirlWind
It's better to use the builtin `getopts` rather than the external `getopt`.
Dennis Williamson
@Dennis: `getopts` supports long option names like `--flag`?
indiv
@indiv: Oh, sorry, I overlooked that requirement. I would use a `case` statement before I would use `getopt`. See [this](http://aplawrence.com/Unix/getopts.html) for a comparison of `getopt` and `getopts`.
Dennis Williamson
A: 

Yes. I'd parse script arguments first and set variables accordingly.

Ingo
A: 

I typically see this done with a case statement. Here's an excerpt from the git-repack script:

while test $# != 0
do
    case "$1" in
    -n) no_update_info=t ;;
    -a) all_into_one=t ;;
    -A) all_into_one=t
        unpack_unreachable=--unpack-unreachable ;;
    -d) remove_redundant=t ;;
    -q) GIT_QUIET=t ;;
    -f) no_reuse=--no-reuse-object ;;
    -l) local=--local ;;
    --max-pack-size|--window|--window-memory|--depth)
        extra="$extra $1=$2"; shift ;;
    --) shift; break;;
    *)  usage ;;
    esac
    shift
done

Note that this allows you to check for both short and long flags. Other options are built up using the extra variable in this case.

Kaleb Pederson
+1  A: 

An alternative to what you're doing:

if [[ $* == *--flag* ]]

See also BashFAQ/035.

Dennis Williamson