[HN Gopher] Argbash: Bash argument parsing code generator
       ___________________________________________________________________
        
       Argbash: Bash argument parsing code generator
        
       Author : ducktective
       Score  : 47 points
       Date   : 2022-03-19 21:24 UTC (3 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | chasil wrote:
       | Why would getopts be discouraged?
       | 
       | Where does the POSIX standard say that getopts is discouraged?
       | 
       | https://pubs.opengroup.org/onlinepubs/9699919799/utilities/g...
       | 
       | https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...
        
         | 0xbadcafebee wrote:
         | getopt is discouraged, not getopts
        
       | eterps wrote:
       | Some thoughts how future shells might tackle this:
       | https://github.com/oilshell/oil/issues/469
        
       | kps wrote:
       | ksh's declarative getopts is easy to use and automatically
       | provides help messages, and is one major reason I use it for day-
       | to-day scripts. It's too bad bash didn't embrace and extend that
       | before they extinguished it.
        
       | q3k wrote:
       | Or, even better: don't use shell scripts to express the kind of
       | complex logic which requires parsing arguments in multiple
       | forms/modes.
        
       | 0xbadcafebee wrote:
       | If you really _really_ want long options, it 's not that hard to
       | just write your own argument parsing function. Certainly it would
       | save you a couple thousand lines of complexity over this.
       | (personally I just use getopts)                 #!/usr/bin/env sh
       | while [ $# -gt 0 ] ; do         x="$1"; shift         case "$x"
       | in           -v|--verbose)              echo "verbose mode" ;;
       | -o|--output)              OUTFILE="$1" ; shift ;
       | echo "Output file is '$OUTFILE'" ;;         esac       done
       | $ ./foo here is -v an option --output foo.txt command here
       | verbose mode       Output file is 'foo.txt'
        
         | egberts1 wrote:
         | Don't forget the end option notation `---`.
         | 
         | As in:                  --)          break        ;;
         | 
         | :-D
        
         | faho wrote:
         | 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.
        
           | rascul wrote:
           | > Okay, now do grouped short options
           | 
           | Seems doable. I may have done it before. I don't have an
           | example handy, though.
        
             | faho wrote:
             | It's _possible_ , yes - by adding yet more easy-to-get-
             | wrong boilerplate.
             | 
             | My point isn't that it's impossible. My point is that it's
             | hard and annoying.
        
               | rascul wrote:
               | I guess I disagree with your point.
        
           | 0xbadcafebee wrote:
           | Agreed! That's why I just use getopts :) Long options are
           | nice but I never seem to need them.
        
           | ramses0 wrote:
           | IMHO, 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.
        
             | cyberdelica wrote:
             | Sorry, 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.
        
             | tsujp wrote:
             | Apple swapped to zsh as the default shell because Bash
             | moved to GPLv3 from GPLv2.
        
             | twofornone wrote:
             | >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 wrote:
               | > 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.2...
        
               | 0xbadcafebee wrote:
               | getopts is actually POSIX so all POSIX-compatible shells
               | should have it. Looks like zsh does:
               | 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/
        
         | mbrock wrote:
         | If you're okay with depending on Git, you can use `git rev-
         | parse --parseopt`.
         | 
         | https://git-scm.com/docs/git-rev-parse#_parseopt
         | 
         | > In --parseopt mode, git rev-parse helps massaging options to
         | bring to shell scripts the same facilities C builtins have. It
         | works as an option normalizer (e.g. splits single switches
         | aggregate values), a bit like getopt(1) does.
         | 
         | > It takes on the standard input the specification of the
         | options to parse and understand, and echoes on the standard
         | output a string suitable for sh(1) eval to replace the
         | arguments with normalized ones. In case of error, it outputs
         | usage on the standard error stream, and exits with code 129.
        
           | unixhero wrote:
           | This is really brilliant and I have never heard of this
           | method before. Noting it down thank you.
        
       | smbv wrote:
       | Is this project still maintained?
        
         | pajamanaut wrote:
         | The maintainer has not had any activity on this project in over
         | a year, but it looks like he account is still active
        
       ___________________________________________________________________
       (page generated 2022-03-22 23:02 UTC)