5 ms·
Okay, now do grouped short options - `yourscript -vo /path/to/file`. Note that getopt(3) (what CLI tools written in e.g. C would use) allows this - `grep -qf /p
by faho 5y ago
Okay, now do grouped short options - `yourscript -vo /path/to/file`. Note that getopt(3) (what CLI tools written in e.g. C would use) allows this - `grep -qf /path/to/file` works the same as `grep --quiet --file /path/to/file`. Come to think of that, you also don't allow `--output=/path/to/file` with the "=".
Argument parsing is one of those things where doing an approximation is easy, doing it correctly is hard.
- 0xbadcafebee 5y agoAgreed! That's why I just use getopts :) Long options are nice but I never seem to need them.
- ramses0 5y agoIMHO, we've reached the point where shortopts for "non-superstar" commands are considered harmful (especially when the command args are used in scripting). Basically, of course, all your posix commands should keep shortopts and keep the "smush together shortopts", but 99.999% of simple scripts and commands that you as a person / developer write should be 100% longopts (and long-opts only!). Bash is a near-dead/dying language in the sense that OSX is pushing zsh, and there are some fundamental flaws in bash that are difficult to consistently work around (eg: see bash-pitfalls and shellcheck). CLI usage is trending towards more "bundle and standardize" (ie: make, npm run, Dockerfile, etc...) and for those purpose I _really_ prefer committing explicit long-opts instead of shortopts (eg: `rm --interactive --recursive --force` v. `rm -irf`), as it's moderately self-documenting and harder to make preventable mistakes. For your whatever internal scripts that parse options, I guarantee you it's better that you explicitly call out `foo.sh --force || foo.sh --file` instead of `foo.sh -f` after you've left it and are coming back to it a year from now. For "superstar" commands like "docker run -i -t ..." then let there be 100k's of users before you start cluttering with shortopts, and only then add them judiciously for truly time-saving interactive uses.
- tsujp 5y agoApple swapped to zsh as the default shell because Bash moved to GPLv3 from GPLv2.
- twofornone 5y ago>Bash is a near-dead/dying language in the sense that OSX is pushing zsh, and there are some fundamental flaws in bash that are difficult to consistently work around (eg: see bash-pitfalls and shellcheck). Recently tried my hand at some bash on osx and was frustrated to find that the osx version of getopt does not support long options, so it looks like there's no portable way to conveniently handle long options on osx, and forcing users to install GNU getopt kind of defeats the purpose of bash (portability)? I guess I don't know the standard, is it reasonable to bundle in a dependency download with a simple bash script (e.g. download the correct version of getopt before parsing args)? I imagine not. How does one properly support long and short options in bash on osx without rolling your own parser?
- rascul 5y ago> frustrated to find that the osx version of getopt does not support long options Probably best not to use getopt, but use getopts instead. In bash, getopts is a builtin. See the link below. http://mywiki.wooledge.org/ComplexOptionParsing#util-linux.27s_special_getopt http://mywiki.wooledge.org/ComplexOptionParsing#util-linux.2...
- 0xbadcafebee 5y agogetopts is actually POSIX so all POSIX-compatible shells should have it. Looks like zsh does: https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Commands.html https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Command... For anyone new to parsing args with getopts, a guide like this might help: https://www.shellscript.sh/tips/getopts/ https://www.shellscript.sh/tips/getopts/
- cyberdelica 5y agoSorry, I completely disagree with practically everything you wrote above. There’s nothing complicated, oblique, or arcane, about short options - if one is versed in Unix. Usually, the sentiment you’ve expressed, comes from the mouthes of developers, more comfortable with Windows, and/or Python - regurgitating cargo cult lore, parrot fashion - sometimes followed with another regurgitated quip, about moving to a “proper” language, if said script, exceeds n lines. A similar phenomenon, can be seen with the Zawinski quote, regarding regex - usually parroted by people who have not learnt regex. If one wants to leave supplementary information, regarding the invocation of anything within a shell script, there is already the facility to do such - comments - which take the same form, as comments within the Python language. Your assertion that Bash is a dead language, is absurd. Particularly when juxtaposed with your assertion concerning Z Shell, immediately thereafter - which is practically identical to Bash, in syntax, aside from a few differences. Command options, short or long, are not even shell specific. They’re a Unix convention. Why should the writer of a shell script, be at all concerned, with anyone who hasn’t grasped the fundamental basics of working with the platform, for which the script is intended to operate?! Personally, I’m of the opinion that long options, are GNU bloat. As for the linked Github repo - getopts - it’s builtin.
- deleted 5y ago[deleted]
- dataflow 5y ago> There’s nothing complicated, oblique, or arcane, about short options - if one is versed in Unix. Need to list a directory reversively? ls -R Need to list a directory in reverse? ls -r Need to sort a list in reverse? sort -r Need to grep recursively? grep -r Need to copy recursively? cp -R cp -r # obsolete! Definitely not confusing!
- ramses0 5y agoThank you, I was trying not to feed the trolls. ;-) http://www.robertames.com/blog.cgi/entries/the-unix-way-command-line-arguments-options.html http://www.robertames.com/blog.cgi/entries/the-unix-way-comm... ...I link to some good references that I found w.r.t. command line options which was a useful baseline even for looking at what options your command may try to support.
- rascul 5y ago> Okay, now do grouped short options Seems doable. I may have done it before. I don't have an example handy, though.
- stephenr 5y ago> doing it correctly is hard What is "correct" though? `grep -iEt file` complains that `-t` is not a valid option (i.e. compressed form of `grep -i -E t`) So Grep does not support passing values to the last of a series of short options that are grouped. But tar does: `tar -cvffoo.tar file` happily creates foo.tar from file. and Python does: `python3.5 -Ec'import sys; print(sys.argv[1:]);' foo` prints `['foo']` and Gzip does: `gzip -kvSsuff file` creates `file.suff` I write a reasonable amount of shell. I've written a number of reasonably complex tools (mostly server admin related but also some more developer focused) in shell. I've written a library in shell, to make writing programs in shell easier. Part of that library does argument passing. Until yesterday it supported short and long opts, with values, without values, with optional values, using space or `=` as a value separator. It also supported short opts with an 'attached' value (i.e. `-fmy-file.txt` in place of `-f my-file.txt`). Yesterday, based on this discussion, I added the ability for it to handle `-abc` (e.g. `-a -b -c` where none of the options expects an argument) or `-abc` (e.g. `-a -b c` where the final option either requires or has an optional argument). So, once again: what is "correct", when it comes to option handling? Your example was grep, but by the examples of other GNU tools, it only does an "approximation".
- faho 5y agoGNU grep doesn't take a value for `-E`, so it interprets this as `grep -i -E -t`, which explains the error. It doesn't have a `-t` option. I don't know of any grep that does take a value for `-E`. It does support taking a value for `-f`, and it also does support that as the last option in a group: grep -qf/path/to/file works, even if path is something like "patterns" (see that "t" in there?). >So, once again: what is "correct", when it comes to option handling? Your example was grep, but by the examples of other GNU tools, it only does an "approximation". I believe you're simply mistaken about what options it takes, and which options take values, the parsing seems "correct".
- stephenr 5y agoWelp yep, the folly of -E vs -e (was someone saying one character options are fine?) You're right that grep does support what I intended to try (`grep -iet`).