Then there's the part where building anything of any significant complexity is not probably a good idea in a shell script.
Then there's the part where building anything of any significant complexity is not probably a good idea in a shell script.
Debian brought the Almquist shell in as /bin/sh, and is maintaining it with strict compliance to POSIX. This displaces bash as the system shell, but bash is still assigned as the interactive shell.
http://gondor.apana.org.au/~herbert/dash/
This is an older standard for the behavior of the POSIX shell. There are many common shell features that are not here (arrays, networking, coprocesses, fancy substitution, and much more). Doing without them increases portability.
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...
Busybox actually takes dash, and then sprinkles a few bash/korn features back onto it (notibly, not arrays).
If you want a lot of people to use your scripts, getting them working in dash can help a great deal.
The POSIX mode in bash exists because bash itself predates POSIX by nearly a decade.
It's like saying you'll never use any Linux feature except those strictly defined by POSIX.1. Why would you do that?
The fundamental reality is that GPL does not run on iOS or Android (in userland). If you want to run scripts on those platforms (and they are ENORMOUS), then you cannot use bashisms.
Full stop.
If your shebang is `/bin/sh`, then it's nice to have a strictly POSIX-compliant shell.
Arrays are still available in POSIX mode, even though they do not comply.
The dash shell has been reported to be four times faster than bash.
That definitely impacts boot time. POSIX compliance is not the only benefit.
The Unix world is better off if there is the option of using another shell that isn’t bug for bug compatible with bash.
This behavior is what leads to systems that have to emulate ancient bloated interfaces because they need to support applications that use apis that are defined as ‘how that program does it’. That’s bad. We should avoid it. Avoiding it is a benefit.
AFAIU correct POSIX scripts will behave correctly with Bash POSIX mode. Incorrect POSIX scripts will not behave incorrectly with Bash POSIX mode as one might expect with a more faithful shell implementation.
IMO Bash POSIX mode is not a problem for running scripts, although you should test your scripts using a strictly shell implementation if you will then distribute those scripts to other users/platforms.
Why not make all your shell scripts #!/bin/bash and anything where that doesn't work is trying to be a second class citizen[1] in unix and so maybe let them? Or tell users to install Bash - which they can probably do if they're using shell scripts..?
[1] Or maybe deliberately trying to break portability by market power abuse.
I know I don't need tell anybody here that Apple is not their friend, merely a supplier who will maximize their revenue at your expense when it suits them.
I will commonly "alias p=printf" in my shell scripts. This is fine in Almquist and bash when called as /bin/sh, but if called as /bin/bash it fails, because bash only honors aliases in POSIX mode.
In bash, reading with a prompt can be done with "read -p prompt var" but this fails in Korn because it's used for coprocesses. This means that your shell script will not run on Android, because mksh is the system shell.
I could probably think of a few more with some effort, and especially a check of the man pages.
p.s. I didn't downvote you.
Aliases certainly _work_ in bash (even when not in POSIX mode. What do you mean by "honors"?
When not in POSIX mode, aliases are only expanded for interactive use.
$ echo '#!/bin/sh \n alias p=printf \n p %s\\\\n "hello world!"' > ok.sh
$ chmod 755 ok.sh
$ ./ok.sh
hello world!
$ echo '#!/bin/bash \n alias p=printf \n p %s\\\\n "hello world!"' > nope.sh
$ chmod 755 nope.sh
$ ./nope.sh
./nope.sh: line 3: p: command not foundIf you haven't run into this, you just haven't written enough for the shell yet.
Once you run into it, you'll not want to write anything specifically for Bash or Zsh anymore unless you know beyond a shadow of a doubt that it will never be run in any other shell.
If you are writing a shell script with the intention of running in many places, fine.
But if you do that, the POSIX compatibility will be the least of your worries.
Because it's not always installed there. See, for example, FreeBSD where bash typically lives in /usr/local/bin/bash. Or in the Linux world, Nix and Guix.
Use "#!/usr/bin/env bash" to account for all these possibilities.
Dunno if anyone here with a better memory remembers the article to link here ...
It depends on your target audience, of course, but Darwin is one of the major current OSs and wanting to support it is reasonable.
> Why not make all your shell scripts #!/bin/bash and anything where that doesn't work is trying to be a second class citizen[1] in unix and so maybe let them? Or tell users to install Bash - which they can probably do if they're using shell scripts..?
Well, for starters AFAIK /bin/bash on Darwin will give you bash 3.2, which is a bit old and feature-poor. Of course you can (and perhaps even should) simply install a new version but then it won't be at /bin/bash, it'll be under /usr/local or /opt or whatever. And BASH isn't POSIX so I'd personally argue that trying to force it makes your stuff the "second class citizen in unix".
Honestly I'm not sure what position you're trying to argue. "Ignore the second biggest desktop OS because they don't ship the latest version of the non-standard scripting language I like"?
There's nothing wrong with that position. Bash is not a "non-standard scripting language people like", it is the de-facto standard on Linux (heck, it was the first program Torvalds ever run on Linux) and the most widespread implementation of POSIX shell in the world. If Apple chosed tivoization[1] over freedom, so I can choose the #!/bin/bash shebang.
That sounds like the definition of not being standardized. BASH is the most common shell implementation on GNU systems (no, not Linux; Alpine is a Linux, and so is Android), but that doesn't make it a standard, only common. It's like claiming that nobody should care about anything but Chrome because it's "the de-facto standard".
> and the most widespread implementation of POSIX shell in the world.
BASH can run POSIX sh scripts, but POSIX sh can't run BASH scripts. If you're only using POSIX features, then it's not a problem, but if you're only using POSIX features we wouldn't be having this argument.
> If Apple chosed tivoization[1] over freedom, so I can choose the #!/bin/bash shebang.
Could I at least talk you into using `#!/usr/bin/env bash` so your scripts will work on a wider slice of the Linux universe? Even on Linux distros that exact path isn't a given (guix and nix send their regards), and you're completely breaking compatibility with the BSDs and illumos distros.
You're also breaking compatibility with newer versions of bash on macOS that almost definitely wouldn't be installed at /bin/bash. I use 5.2 from brew.
if bash isnt posix then wth is? if you told me "British English isnt actually English" I'd be less surprised than bash and posix.
No
> if bash isnt posix then wth is?
POSIX sh (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...).
That's why bash scripts can be interpreted on any OS from 1995 to now and Rust can only be compiled on an OS which has updated it's rustc in the last 3 months.
Gotta hand it to Bash devs. They do a good job.
You can get the same effect by trying to run scripts with bash 5.x features on a version of bash from 1995.
Rust code since 1.0 has the same level of backwards compatibility that bash does.
That's true and exactly what I said. It's the rust developer demographic that lacks the consideration to write backwards compatible code.
Backwards compatibility isn't really about whether you can run code on _old versions_, but if you can run _old code_ on new versions. Scripts that were written with Bash 1.14 should work today (barring all the other external dependencies they may have...), but scripts that are written today won't necessarily work on 1.14.
That's the same as the Rust analogy: code written with Rust 1.0 should compile and run today, but code written today won't necessarily work on Rust 1.0 (albeit, there must be a subset of new code that would happen to work).
Ah, sorry, I guess I mean forwards compabitibility then. The ability to interpret/compile code written by devs today on machines with software from years ago (or months ago in rust's case).
If your shell scripts are small, it's easy to write several versions of them.
It they are long, you should use something else than shell scripts for your program, like python.
Worse case scenario, provision the same interpretter everywhere, vendor it, or use a compiled language.
There are some edge cases where portability makes sense (e.g: you are scripting for an heterogeneous parc of routers), but they are niche usages most companies don't care about.
Busybox bundles the Almquist shell, and there is a Windows port available. This is the easiest and least intrusive way to run shell scripts on Windows.
Busybox advertises that it bundles bash, but this is not true - it's Almquist with some added bashisms.
It also bundles their own awk implementation, but not Tcl/lua/lisp/scheme.
In fact, as soon as you need to use arrays, it's game over.
>In fact, as soon as you need to use arrays, it's game over.
Why?
PS. comfortable with both. I don't draw lines based on LOC or arrays.
ShellCheck is a great tool, yes, and can be run natively inside your IDE. Just like any language, you need to learn the language and learn it's tools.
Blanket statements like "write all your scripts in python because there's less bugs" really just means the commenter is more familiar with python. Do enough script writing and you'll realize how absurd that statement is.
It's a lot like the folks that scream nobody should ever write a single line of C or C++ because it's "dangerous" - yet untold number of lines of C/C++ are written every day. A pencil can be dangerous in the wrong hands...
BTW both shellcheck and mypy are equally optional, so I'm not sure what your high horse is about.
Still, the vast majority of IT projects do not fall in that category.
It exists, but it's a very, very small % of why you need a bash script. And in fact, even those advocating for bash portability almost never fall into the category of people that have to do it in their daily job.
I'll go even further and even state that a lot of embedded system don't even have bash scripting capabilities in the first place.