If you were to write Python code that did a of its business logic by spawning new processes rather than using its core libraries (which are written in C) then you’d find Python would be just as slow too.
But the exact point of Bash and other shells is to make launching new processes easy. This is the point that people miss when they say “write it in a real programming language”. Shells solve an entirely different problem to other languages. And “real” programming languages suck at working with other executables in a quick and convenient way.
Also for this to be really unique and good it needs insanity like being able to avoid all external dependencies, or else idempotently installing them in ways that can not affect anything else externally, or even temporarily, in multiple crazy various environments including nix? my mind never shuts up
You'll run into the Alternative Implementation Problem
https://pointersgonewild.com/2024/04/20/the-alternative-impl...
https://news.ycombinator.com/item?id=40337036 - 10 days ago, 84 comments
Relevant excerpt:
> You may read this and think that the key lesson of this post follows the old adage that “if you can’t beat them, join them”. In some ways, I suppose it does. What I want to say is that if you start a project to try and position yourself as an alternative but better implementation of something, you are likely to find yourself stuck in a spot where you’re always playing catch up and living in the shadow of the canonical implementation.
This concept doesn't exactly map 1:1, but gist seems correct. Who wants to program in a worse and very limited version of Python? Who's going to keep things up to date in e.g. Amber as Python continues to evolve? Not fun.
- nushell
- elvish (was featured on HN recently)
- powershell
- murex (disclaimer: I’m the author of that one)
Most of the value in sh to me is that it’s ubiquitous. I write a script and the runtime is already available across most devices, operating systems, containers, and everywhere else without an extra steps.
It's unfortunate Amber doesn't have a Map data type, pretty big limitation.
I can think of ways of doing it, e.g. something along the lines of:
* Set the constraint that all keys must be of type String
* Then abuse /dev/shm/.Amber/${pid}/${func}/<put keys and values in files somewhere under here>
For example, we had an EC2 machine whose init would fetch and run a shell script from S3, which spun up a big JVM application. We started getting strange errors from deep inside the JVM, which seemed to be caused by some security update somewhere in the stack (either ours or Amazon's); but that machine image had evolved via snapshots of snapshots, etc. and was a pain to figure out what it was running, let alone update and manage it in a sane way. As a quick fix I bundled a known-good JVM into an Arx file (along with other dependencies like Bash, etc. since it's Nix, so I might as well!) and put that on S3 in place of the old shell script. That got the EC2 machines working again, without having to mess with the (already messy) image; we gained a more sensible way of specifying dependencies (via Nix); and, since we were now building an artifact, rather than slinging a raw script, we could do stuff like running Shellcheck on the code. This definition was also easy to re-use when we eventually switched it to ECS containers (just changing the `nix bundle` options).
I want to do more complex things using bash for devops stuff, because it's mostly working with other command line tools. You could directly use APIs and SDKs of cloud providers, but then things become an order of magnitude more complex than just writing the bash script.
However, when you do that you encounter bash's weaknesses, like not supporting a nested structure like Map<String, Map<String, Int>> and so on. Having to wrangle tools like jq, sed and awk all together to work around the lack of proper data structures and string manipulation is no fun either.
Something like amber could bridge the gap while still being portable across systems.