Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Possible Duplicate:
How do I handle switches in a shell script?

Most common shell commands allow the user to specify options in any random order. Positional Parameters like $1 as commonly used in bash (I tend to write all my scripts in Bash but I don't think this question is actually Bash specific) scripts on the other hand, are order specific.

Now I could come up with some way to remove the need for the user of a bash script to observe any particular order in the supplying of optional arguments. (Using regular expressions or globs to test for the presence of some particular option in the $@ expansion comes to mind.) However, I am really trying to find out whether there is a particularly canonical way to implement such options. Given the common syntax for options like -r for many shell commands I certainly feel there should be.

share|improve this question
add comment

marked as duplicate by jw013, Renan, Michael Mrozek Sep 25 '12 at 16:55

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1 Answer

getopt and getopts support any order for the given arguments - They're easy to use, and seem to be the canonical solutions to argument parsing.

Two differences which are often mentioned:

  • getopt supports long options like --help.
  • getopts is a Bash shell builtin rather than a standalone program.

Simplified extensive example:

# Process parameters
params="$(getopt -o e:hv \
    -l exclude:,help,verbose \
    --name "$0" -- "$@")"

if [ $? -ne 0 ]
then
    usage
fi

eval set -- "$params"
unset params

while true
do
    case $1 in
        -e|--exclude)
            excludes+=("${2-}")
            shift 2
            ;;
        -h|--help)
            usage
            exit
            ;;
        -v|--verbose)
            verbose='--verbose'
            shift
            ;;
        --)
            shift
            if [ -z "${1:-}" ]
            then
                error "Missing targets." "$help_info" $EX_USAGE
            fi
            if [ -z "${2:-}" ]
            then
                error "Missing directory." "$help_info" $EX_USAGE
            fi
            targets=(${@:1:$(($#-1))})
            source_dir="${@:$#}"
            break
            ;;
        *)
            usage
            ;;
    esac
done
share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.