Bash is "real language" if you treat it as such. Yes, there are plenty of spaghetti scripts out there, riddled with global variables and full of side-effects, but if you write shell in a principled manner, you can solve some pretty big problems with ease, and you can write maintainable code.
I wouldn't start new projects in shell, of course, but one area in which I think the shell shines is in writing integration tests for tools. More on this in a recent post I wrote: https://jmmv.dev/2023/10/unit-testing-with-shtk.html
> Bash is "real language" if you treat it as such. Yes, there are plenty of spaghetti scripts out there, riddled with global variables and full of side-effects, but if you write shell in a principled manner, you can solve some pretty big problems with ease, and you can write maintainable code.
Even carefully written bash code tends to be much less maintainable than code in better languages. It's just badly designed on multiple levels, like the famous post about PHP. Yes, if you're really careful you can write decent code in Malbolge - but why would you?
> I wouldn't start new projects in shell, of course, but one area in which I think the shell shines is in writing integration tests for tools. More on this in a recent post I wrote: https://jmmv.dev/2023/10/unit-testing-with-shtk.html
The fact that you've written something that compiles to shell scripts rather than writing shell scripts rather undermines your claim that shell is a decent language. Integration tests of tools are important, but I'd still find e.g. TCL a much better way to write them.
> but if you write shell in a principled manner, you can solve some pretty big problems with ease, and you can write maintainable code.
So if you are extremely good at writing shell, and you write it extremely carefully, then you can achieve basically what you can do in other languages without those caveats?
It sounds like we both agree that shell is not a sensible choice for scripting, for most people, then.
The same can be said about QBasic as well, honestly. And here's the catch: people who are inclined to write anything in a principled manner are likely the ones who'd write things in a principled language instead of e.g. shell. Or to put it in another way, if someone chosen to write in shell (or failed to consider an alternative, which also happens quite often), they're quite likely exactly the person to not write anything in a principled manner.
I think one of the Rust's creators (or was it Go's?) said that they wanted to get the C++ developers to switch to their language but that didn't happend, they unexpectedly got Python developers instead but retrospectively it makes sense to them: people who wanted to switch from C++ and could afford to had done so already, so the C++ developers are the people who either don't mind C++ or the people who have to write it.
Which brings me back to my point: yes, technically you can write decent code even in a sloppy language but that misses the bigger picture which is that most of the code written in a sloppy language will inevitably be sloppy because most of the people who write it won't care, due to the dynamics described.
Heck, the Ops department in my org was forced by the security guys to globally enable ShellCheck on commit for their internal repos, and those security guys still have to drop by about every 2-3 months to rip away their "# shellcheck disable" pragmas and force them to actually fix their broken code because those people in the ops actively don't care. The Ruby scripts they write end up slightly less broken because Ruby itself is a slightly more principled language, not because they suddenly care more when they write Ruby.
Not to mention myself: I've spent quite some time and energy on learning shell's semantics and tricks and quirks and DOs and DONTs but it's such an infinite, never-ending descent into abyss with rewards of dubious value that nowadays I just don't care. Whenever I have to write a one-off script, I give up even before I start and write it however sloppy, with minimal quoting, to save my time; and only when it breaks, or when I have to reuse it, or when I have to share it — which happens quite rarely — then I re-write it in a proper language. On the whole, that definitely saved me both my time and my sanity. As for the cases when I have to write properly behaving shell script, well, those are almost arise in the course of the tasks that can be delegated to our ops team and now that's their problem.
P.S. I found that re-writing naive but broken shell scripts in a proper language is quite easy: the intended semantics is generally obvious, it's just the shell that actually requires quirkier syntax to propely express it; re-writing the (mostly) non-broken shell scripts is much harder: you have to decipher the intended meaining from the quirky syntax while keeping in mind that the original author still could have gotten it wrong by not knowing about a particular quirk you're aware about (or vice versa).
I agree. If a POSIX shell script serves your needs, use it. If it doesn't, you shouldn't be reaching for a more powerful shell, but an actual language. I'd reach for Perl before Bash, and I can't stand Perl.
People would had such a take and tell to use perl twenty years ago. Looks where we are now. I'd rather have improved my shell scripting abilities right away.
It's a three (optional) steps thing really:
- I want something that can use on multiple systems right away (shell)
- Ok things getting a bit serious, I'll allow myself to add some pre-requirement tooling on the system (others script)
- pre-requirement sucks, I'll invest in native code tooling and produce binary (eg rust & go for the choices of the moment).
Agreed. If your shell script has more than the most basic of functionality, you should probably write it in literally any other language. Like another poster said: I don't like perl, but I'll take it any day of the week over bash.
Honestly, I think writing a Bash script is just a terrible idea. Use a real language, and all of these nightmares go away.
For me, lately, that's been Zx (which uses Node), but there are other fine choices too.