Design Considerations for the getopt_long Portable Command
I have a getoptx program that works with single-letter options (therefore, this is not the answer to your problem), but it correctly processes arguments with spaces, and the original getopt command (unlike the shell, built-in getopts ). The description in the source code says:
/* ** Usage: eval set -- $(getoptx abc: " $@ ") ** eval set -- $(getoptx abc: -a -c 'abc' -b abc 'de f') ** The positional parameters are: ** $1 = "-a" ** $2 = "-c" ** $3 = "abc" ** $4 = "-b" ** $5 = "--" ** $6 = "abc" ** $7 = "def" ** ** The advantage of this over the standard getopt program is that it handles ** spaces and other metacharacters (including single quotes) in the option ** values and other arguments. The standard code does not! The downside is ** the non-standard invocation syntax compared with: ** ** set -- $(getopt abc: " $@ ") */
I recommend the notation eval set -- $(getopt_long "$optspec" " $@ ") for your getopt_long .
One of the main problems with getopt_long is the complexity of the argument specification - $optspec in this example.
You can look at the notations used in the Solaris CLIP (Command Line Interface Paradigm) to indicate; it uses a single line (for example, the original getopt() function) to describe the parameters. (Google: "The Solaris Clip Command Line Interface Paradigm", using only the "tanning clip" will take you to video clips.)
This material is a partial example derived from Sun getopt_clip() :
static const char *arg0 = 0; static void print_help(void) { printf("Usage: %s [-a][-b][-V][-?][-f file][-o file][path ...]\n", arg0); printf("Usage: %s [-ascii][-binary][-version][-in-file file][-out-file file][path ...]\n", arg0); exit(0); } static const char optstr[] = ":a(ascii)b(binary)f:(in-file)o:(out-file)V(version)?(help)"; int main(int argc, char **argv) { int c; char *filename; arg0 = argv[0]; while ((c = getopt_clip(argc, argv, optstr)) != -1) { ... } ... }
source share