getopt is external command from util-linux and getopts is Bash builtin. When I was coding a C code, I learned that getopt of unistd.h not only having required argument : but also optional argument :: (double-colon), that means you can do things like:
while ((opt = getopt(argc, argv, "o::")) != -1) { switch (opt) { case 'o': if (!optarg) dummy = DEFAULT_DUMMY; else dummy = process_dummy(optarg); break; } }
From getopt(3):
Two colons mean an option takes an optional arg; if there is text in the current argv-element (i.e., in the same word as the option name itself, for example, “-oarg”), then it is returned in optarg, otherwise optarg is set to zero. This is a GNU extension.
Unfortunately, this, ::, isn’t supported by Bash’s getopts or specified in getopts(1P) of POSIX Programmer’s Manual since it’s a GNU extension. So you will probably need to parse by your own or use util-linux‘s getopt command:
eval set -- $(getopt -- o:: "$@") while (($#)); do case "$1" in -o) dummy=${2:-$DUMMY_DEFAULT} shift 2 ;; --) shift break esac done
This is actually looks more or less like parse-by-yourself, see the shift?
From getopt(1):
[…], and by two colons to indicate it has an optional argument.
If the option takes an optional argument, but none was found, the next parameter will be generated but be empty in quoting mode, but no second parameter will be generated in unquoted (compatible) mode. Note that many other getopt(1) implementations do not support optional arguments.
I don’t have much experience with either, but I quite like this getopt since it can handle -- and has long options, former is also supported by getopts but not latter.
The only thing I don’t like is the use of eval, but I think I can live with that. If I insisted not using eval, I could use an index, go through the array returned by getopt, ((index += 2)) rather than shift 2.
Another thing has to be careful is the portability, on Linux distribution, it should be fine, but if for other Unix-like system, this might not work since the manpage already told us so.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.