maybe that's the compelling use of scripting with a statically typed, thus compile-time at least partially low-hanging-fruit-error-checked, language?
IMHO writing procedural style code with lots of if, loops, etc. in the shell can quickly turn into an anti-pattern. Try to stick to simple functions that are chained together in pipelines. The only loop is typically one that processes arguments and that's it.
Bash is incredibly less complex than Javascript and there is such a resource: the "Bash guide" [1] and "Bash pitfalls" [2] are both excellent resources that teach you how to use Bash properly.
Oh, but which version, 2 or 3?
Bash availability may not be guaranteed, but a POSIX shell of some variety is.
Shellcheck has dramatically increased the ease by which you can write decent scripts before ever running them. But I also have never seen any language that anyone could master without a year or more of constant use.
For example, you could in your scripting language use `find` to search for files in a folder and do something with them, but why do that when your language of choice almost certainly has globbing capabilities? You could grep a file for a line, but why do that when you can use your language's inbuilt regex system?
At least from the scripting side, the reason I tend to push more towards using the language and less towards using external processes is because most scripting languages can do what those external processes do in one go.
Perhaps it would make more sense if I were better at defining scope :)
I did manage to make a Windows batch file that replicated the functionality of a linux/mac bash script, but configuring it was no fun for customers on any platform, and then there were the utilities themselves to deploy.
The replacement binary has a very small platform-dependent aspect, and I am not held back by the limits of batch files when trying to achieve feature parity.
It might be doable to deploy a powershell script, but then there's installation work to do on the unix side instead.
This is the approach that I took with murex. It comes with a stack of builtins for json, jsonlines, yaml, toml, csv, sqlite3, and others. So you have all the power of data types and intelligent management of structured data but also works with regular POSIX CLI commands without any additional boilerplate code when swapping between murex code and coreutils (et al). So one could say I’ve spent a fair amount of time studying this point you’ve raised :)
(Don't be afraid to self promote!)
One obvious benefit over what's suggested in the article is that you can use it interactively first, with autocomplete and such goodies, and transition smoothly to a script later.
The biggest benefit of the shell is its clearly defined input and output (and error) interfaces. Most programming languages can read from and write to stdin, stdout, and stderr.
Why not use it and stick to KISS, replacing one cumbersome POSIX utility at a time, suites for the task? Then you don’t need to chain methods using less idiomatic code. But then you wouldn’t need these kind of libraries either.