For example: https://github.com/nickjj/docker-flask-example/blob/main/run
In a bigger project this file tends to grow quite large, even when you have the power of a programming language available to you there's plenty of tasks where it makes sense to keep it as a shell script. Now imagine you work on a team where other folks want to contribute new functionality, it's important to have automated tools to help stick with a consistent style, just like you would want to use Black with Python.
The run script for my infrastructure repo at one place I work for is almost 1,500 lines of shell scripting that's broken up into many small functions. It's not a big jumbled mess either, it's very organized and optimized to make running long commands faster and less error prone (even if they happen to be called in CI). These functions are mostly calling out to Terraform and other tools too, it's not 1,500 lines because of long winded cloud CLI tool API calls or anything like that.
[0]: https://nickjanetakis.com/blog/replacing-make-with-a-shell-s...
- Self contained in one file
- Easily edited with vi/nano (i.e. through a console ssh session)
- Readily available on most Linux base installations
- No crazy runtime installation requirements
Edit: formatting)
How are you gonna handle installing that beautifulsoup dependency in a way that does not bork the OS python deps?
Are you gonna use `python -m venv` or `poetry` or `pipenv`?
If it is for work: either Bash or whatever that companies preferred software development language (over the last ~20 years that's included: Pascal, Visual Basic, PL/SQL, Perl, PHP, Python, Typescript and others I've likely forgotten. Different companies will have different preferences)
If performance matters then these days Go is my "goto" language because it's a good compromise in terms of developer productivity and application performance. But I've used Java, C and C++ too. Depending on the particular problem I'm trying to solve.
...and if you ask me again in 5 years then the answer will be completely different again.
The sort answer is: there's no such thing as a single answer. Everyone will have their own preferences and business requirements.
It depends on what I'm doing but usually Go if an application requires any longevity at all.
I use Python or Java for things that require more dynamic typing. The main usecase here is big data or to prototype applications.
Bash I usually reserve for very small tasks. When I bootstrap services in containers, you'll usually find some Bash. A whole CLI written in Bash? I would not approve that PR. Bash lacks variable scoping for the most part, the ways in which you can implement it are hacky and non-obvious. Bash's syntax and the way it behaves varies by system, even installer scripts have to account for this. As I'm typing this, I realize the Bash code I write generally follows the same testing and constraints as the Makefiles I write.
I don't think I really understand the requirement for "a single document". This departs from programming practices I've built up over the years. When I come across large multi-thousand LOC documents (in any language, much less Bash) I'm usually concerned.
Those tasks that I use bash for are usually one-offs, and live on the server they are used on.
Thus, it should be easy for the next admin/Dev to find it and understand/fix/extend it.
Of course, if there is a more advanced task those requirements fall short and there should be a proper Dev env with source control, tests, etc.
POSIX mistake number 1: Bash isn't available everywhere, even when restricted to Linux. Even Debian avoids bash for a good reason (Bash is slower than most POSIX shell implementations), although it's installed by default for convenience.
:-/
Things like docker images and nix builds are sold as huge improvements on this chicken-egg problem, at least from a "keep it all in one language" perspective, but only if you consider a docker script (mostly bash) or a nix config truly not the same thing as a shell script that more or less initiates the same environment.
docker/nix abstraction layers have advantages but aren't always as portable as a shell script. If you need a docker engine, I think you'll still need a bash script to install that...
Nix is possibly even more "single command", often just a curl if i'm not mistaken, but still requires config and shipping a build somewhere, and you still need to run the `curl` command in a shell somehow. i don't see how "just use python" will ever fix the init chicken-egg problem.