I have to admit, while i admire the idea of and understand the reasoning behind striving for POSIX-compatibility, i never couldn't fully get past viewing this as some kind of hypothetical exercise. The chance that any script i (or presumably most people who get this advice on pages like SO) will ever write will have to run on a 25 years old Tru64 machine or even a modern Mac, BSD, QNX, … is relatively small. Truth is (in my case), most of the scripts will never even run on anything but the system they were written on. As i said, i admire the idealism though.
First, we get rid of PATH= inside scripts. A lot of incompatibilites comes from /bin, not the shell itself. Treat executables like services, rewrite everything (reasonable) in pure shell.
The scenario I'm trying to prevent is "I want to cut a string in OSX but I wrote for a GNU executable and the syntax is slightly different". Most shell one liners can be rewritten as good quality portable code.
If you take just Debian, there are 5 or 6 shells available via apt. These should run wherever Debian runs (x86, arm, hurd, whatever).
You can't write a reasonable JavaScript that runs on JScript.exe (it still exists), Apple JXA, gjs and node.js. But you _could_, the language is stable enough, for long enough, that everyone knows how to feature detect the shit out of everything js related.
For the shell though, we don't even have a solid list of things that work or not in each shell, or differences across core utilities. Something like caniuse.com, but for UNIX shells, not browsers.
Having a page that runs on all browsers was once something impractical and idealistic. Not using tables and invisible 1x1 pixels for layouts was once idealistic. We fixed it though. Mostly.
But the reason to use POSIX scripting isn't portability, it's simplicity. Simple scripts are just easier to reason about, easier to maintain, and are less prone to bugs. The code might be a little more verbose, but its simplicity still reduces the cost of complexity.
Most people don't realize this until they've been writing scripts for 15 years and realize they can do almost everything with POSIX and that it makes their life easier in the long run. But in some cases what I want to do would really benefit from Bash, so I use Bash then. It's not a hard and fast rule; I switch based on what would work best for that case. It's about balance, compromise, and being flexible.
Bold claim and patently untrue because I have read the whole manual.
However:
1) Things you don't use often leak out of your brain at a rate that is absurd.
2) Different versions have different features and there's wide variations between versions on different platforms, you can't actually depend on a lot of bash stuff existing, so instead it's usually better to target POSIX sh
I once thought I’d solve this by taking notes, organizing a journal, and writing ... Well, it was a manual. That had the same problem as other manuals - too long, not gonna read.
Full circle.
Despite all this, my brain is still Swiss-cheese.
Here's the link to the latest official manual on GNU's site:
https://www.gnu.org/software/bash/manual/html_node/index.htm...
Except that doesn't disable all bashisms so you end up leaving in bashisms as a result, which is what caused all the issues for debian trying to migrate to dash
$ man bash | sed -n '/BUGS/,/^$/p'
BUGS
It's too big and too slow.
It is at this point that such a reader will discover the reasons behind Debian dash.
Nobody who has ever used Bash has read the whole manual. It is actually good and useful, please read it. Yes, it is very big. But you will be using this shell for the rest of your life (even if you use Zsh, you will end up using other people's Bash scripts). Consider it an investment in your future.
...and now that I say that - try to restrict shell scripts to POSIX semantics (https://betterprogramming.pub/24-bashism-to-avoid-for-posix-...). POSIX is very simple and most shells can run it. If you need a Bashism, try Bash v3 first so it works on a Mac without Homebrew. Simple is better/portabler than complex. If you need something Bash doesn't provide, use any language that the majority of your team knows well.
If you want to test a specific version of Bash, there's containers @ https://hub.docker.com/_/bash (Macs use v3.2.57). Test POSIX scripts with `bash --posix`. Definitely use Shellcheck.