Open l0b0 opened 2 years ago
For example, here's a bog standard use of getopt AFAICT covering the vast majority of use cases:
I might as well leave this here…
getopts
supportHere's the snippet version for editors that use TextMate-flavoured snippets (VS Code, Atom, Sublime, TextMate, etc).
Isn't getopt
broken everywhere outside Linux? (https://mywiki.wooledge.org/ComplexOptionParsing)
I've actually came across this issue, because I was wondering how to make ShellCheck warn against use of getopt
Using getopt would be really good if the support was fine but there may be cases where getopt isn't supported (most Android), but also case where it is supported but not completely (for example lack of support for long options). So for those that need compatibility it is mostly a problem.
Do not use getopt
for portability. Except for the GNU version of getopt
, it not only cannot handle long options, but also cannot handle arguments that contain spaces. Below is the macOS (FreeBSD) version of getopt in action.
$ ./test.sh -a -o "a b"
-a
-o: a
Not implemented: b
$ ./test.sh -a "a b"
-a
rest arguments:
a
b
#!/usr/bin/env bash
arguments="$(getopt abco: "$@")"
eval set -- "$arguments"
unset arguments
while true
do
case "$1" in
-a | -b | c) echo "$1"; shift ;;
-o) echo "$1: $2"; shift 2 ;;
--) shift; break ;;
*)
printf 'Not implemented: %q\n' "$1" >&2
exit 1
;;
esac
done
echo "rest arguments:"
for i in "$@"; do
echo "$i"
done
For new checks and feature suggestions
Here's a snippet that shows the problem:
Here's what shellcheck currently says:
Here's what I wanted or expected to see:
Rationale: It’s tempting to implement basic option handling yourself when there’s only a single option. But there are plenty of pitfalls, and I’d recommend using
getopt
from the start. For example, here's a bog standard use ofgetopt
AFAICT covering the vast majority of use cases:Doing everything this does manually would be a lot of work:
--configuration=foo
and--configuration foo
call styles.--
option/argument separator. If this separator is not part of the original command it's added after all recognised flags, so there's no ambiguity about when to break off the loop.--options=''
is unfortunately still necessary to specify that I definitely don't want to support any short option names).--configuration
is specified more than once, the last value is used. This is a common solution to allow a default set of options (for example in a configuration file) which can then be overridden by command-line options. It would be easy to change the example toexit
instead, if that's what you want.--include
values in an array, making them safe to reuse.getopt
call which is not yet handled by thecase
, which would be a programmer error. This case is handled gracefully.