
Bash Argument Parsing and Quoting (2016) - luu
https://www.jefftk.com/p/bash-argument-parsing-and-quoting
======
RcouF1uZ4gsC
Bash is a great argument for the fact that it is not so much the features of
the language that matter, but what ecosystem it is a part of. Bash is popular
because it is the default scripting language of the shell in Unix. Javascript
is popular because it is in all the browsers. C is popular because it is the
default compiled language of Unix. Objective-C became popular because it was
the default programming language of the iPhone.

~~~
chubot
Yeah this explains why and predicts that Kotlin and Swift are popular, because
Android and iOS now use them.

It also explains PHP, because PHP was tightly integrated with Apache via
shared library, and in the 90's, lots of hosting providers were spinning up
LAMP.

So basically if you wanted to buy hosting in the 90's, you could pay $20/month
for shared PHP, or $200/month for a dedicated box running Perl.

PHP creator Rasmus had a good talk about that recently. So shared hosting was
essentially "remote OS" that was cheap.

\-----

Exceptions to the rule: Python and Ruby. People installed them because they
were nicer languages, and mainly used them on the server side. But Python even
made it to the client side in many instances because people like the language!
(Dropbox, IPython/Jupyter, etc.)

bash was the default on Linux, which was huge. Other Unixes like Solaris and
BSDs used other shells, but yeah it does seem true that bash was helped along
by Linux.

I think Linus said that bash was literally the first program that ever ran on
Linux, which made sense. Before that I guess bash was run on Solaris and
commercial Unixes, and wasn't that popular.

------
jwilk
> Replace \ with \\\, ' with \', and wrap each argument in 's if it contains
> anything suspicious.

This is not a correct way to do shell quoting.

The code doesn't quite follow this description, but it's not correct either:

    
    
        $ tmp=$(printf '\nX')
        $ newline=${tmp%X}
        $ printf '['; quote "$newline"; printf ']\n'
        [
        
        ]
    
        $ quote 'foo+\bar'
        'foo+\\bar'

~~~
kanox
The easiest way to quote for the shell:

* Add ' at the beginning and end

* Replace internal ' with '\''

This is because inside '-quoted string only ' itself has special semantics.

> wrap each argument in 's if it contains anything suspicious.

Such vague advice is wrong in all contexts.

~~~
pizza234
I wouldn't rely on a manual mean, considering that there is a built-in API:

    
    
        printf '%q' <string_to_quote>

------
chubot
Related to quoting, Oil has a way to opt out of needing it everywhere, which I
documented here:

 _Simple Word Evaluation in Unix Shell_

[http://www.oilshell.org/release/latest/doc/simple-word-
eval....](http://www.oilshell.org/release/latest/doc/simple-word-eval.html)

 _parsing and evaluation aren 't interleaved, and code and data aren't
confused_

 _No Implicit Splitting, Dynamic Globbing, or Empty Elision_

 _Opt In to the Old Behavior With Explicit Expressions_

Also related: _Oil Doesn 't Confuse Flags and Files_
[http://www.oilshell.org/blog/2020/02/dashglob.html](http://www.oilshell.org/blog/2020/02/dashglob.html)

------
tsuyoshi
If you want to parse complicated strings using only a POSIX tool, and put the
results into an array, you're better off using Awk.

------
databasher
Why not use bash's printf %q?

    
    
       string=$(printf ' %q' "${array[@]}")

~~~
jwilk
In Bash ≥ 4.4, you can also use parameter transformations:

    
    
        function quote() {
          echo "${@@Q}"
        }
    

(In both cases, the generated output is understood bash, but not necessarily
by other POSIX-compliant shells.)

------
Domenic_S
When writing bash scripts, I use shellcheck.net to help find problems like
this. It's great!

------
mkchoi212
I could never imagine building an arg parser with bash. But A brilliant
solution I must say :p

------
cfstras
shellcheck. It's great. Use it.

It has plugins for most IDEs, and just reading the wiki entries for the error
messages you encounter will teach you a lot of useful things about bash.

~~~
deeblering4
came here to say this!

------
benburleson
Does `getopts` not handle this?

