The Shell Scripting Tutorial: Parsing long command-line arguments with getopt
This is a little tutorial that I found in my search to learn how to use getopt (mind: not getopts, which is a completely different thing). I want to share it here because I find it refreshingly to the point. Just the main code block already tells almost the whole story:
#!/bin/bash
# Set some default values:
ALPHA=unset
BETA=unset
CHARLIE=unset
DELTA=unset
usage()
{
echo "Usage: alphabet [ -a | --alpha ] [ -b | --beta ]
[ -c | --charlie CHARLIE ]
[ -d | --delta DELTA ] filename(s)"
exit 2
}
PARSED_ARGUMENTS=$(getopt -a -n alphabet -o abc:d: --long alpha,bravo,charlie:,delta: -- "$@")
VALID_ARGUMENTS=$?
if [ "$VALID_ARGUMENTS" != "0" ]; then
usage
fi
echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS"
eval set -- "$PARSED_ARGUMENTS"
while :
do
case "$1" in
-a | --alpha) ALPHA=1 ; shift ;;
-b | --beta) BETA=1 ; shift ;;
-c | --charlie) CHARLIE="$2" ; shift 2 ;;
-d | --delta) DELTA="$2" ; shift 2 ;;
# -- means the end of the arguments; drop this, and break out of the while loop
--) shift; break ;;
# If invalid options were passed, then getopt should have reported an error,
# which we checked as VALID_ARGUMENTS when getopt was called...
*) echo "Unexpected option: $1 - this should not happen."
usage ;;
esac
done
echo "ALPHA : $ALPHA"
echo "BETA : $BETA "
echo "CHARLIE : $CHARLIE"
echo "DELTA : $DELTA"
echo "Parameters remaining are: $@"
Just be sure to correct the inadvertent mixing of beta and bravo.
https://www.shellscript.sh/examples/getopt/Open linkView original on programming.dev
If you find yourself needing this, the correct thing to do is to stop writing that shell scripts and switch to a proper language.
While I agree with you, I think it's a bit unkind to reply in this way. Sometimes bash is all you have, and it's interesting to learn about tools even if you're unlikely to use them.
Bash is everywhere—embedded systems, minimal containers, legacy servers. Zero dependencies, just #!/bin/bash. In constrained environments, you often can't install "proper" languages. It's often the right and only tool for the job.
I've got one from stackoverflow i tidied up and expanded, that handles long options as well, but you really should learn Python instead. Talking from experience; even with a state machine approach and helpful little functions and debug helpers, juggling so much input is hard in shell.
Well, you're warned now and here it is:
I still think my favorite shell, NuShell, handles this the best:
So much less boilerplate
There is also the manual way, I am not saying it's perfect but sometimes it offers better alternative than getopt.
https://gist.github.com/dgoguerra/9206418
The article mentions "GNU getopt" but as far as I know GNU doesn't have a
getoptutility; the version on most Linux OSes comes from util-linux. (Perhaps the author is confusing it with the C function with the same name.)Note that other
getoptimplementations have different features and some are simply broken. For example, BSDgetoptdoesn't support long options and comes with this known bug:For cross-platform scripts it's probably best to use the
getoptsshell builtin instead, the downside being it only supports fairly basic (POSIX) syntax even on Bash.