Ask HN: Why is bash a popular scripting language?
Looking for opinions here. Is bash simply popular because it is always available and so there's nothing inherent that makes it popular?
Or, is there something special that it has? Writing a bash script seems very different to the rest of the programming I do. And not often in a better way.
What are the most interesting, alternatives for simple scripts.
37 comments
[ 2.6 ms ] story [ 81.4 ms ] threadAfter a while you will appreciate that the script you wrote 10 years ago still works everywhere, and that new shiny thing that was supposed to replace it died and withered away instead.
This question leads to the classic xkcd standards problem: https://xkcd.com/927/
IMO almost any modern scripting language is totally up to the job of being better than bash for larger scripts. Python, Ruby, Lua, etc. all have facilities to access the filesystem and run external commands while also giving you things like modules and classes as ways to organize your code. The former is essentially table stakes for this kind of job, while the latter is what starts becoming useful once you pass a certain size threshold. 25 lines is, of course an arbitrary threshold, but it seems reasonable enough for me.
Bash "just works" for the majority of UNIX-like systems. Even if you don't have bash installed, there's a good chance you've got a simple interpreter that can run a script file like zsh or sh.
There are reasons one might use Python, but I always reach for bash when I'm doing sysadmin or text processing work.
Like Bash, Perl is also widely available, more concise and faster than Python, and more of a full programming language than Bash.
People love to 'hate on' Perl, but how many of them have actually used it?
Most Linux and Unix systems include Perl by default and Perl-compatible regular expressions are the defacto default. For quick and dirty, non-Bash scripts Perl is an excellent choice.
So what's important is that the system already has the language installed and so it's not worth considering options you need to install yourself.
OP asked, "What are the most interesting, alternatives for simple scripts."
My answer is Perl is a useful alterative to Bash for simple scripts.
I did not say that other scripting languages that needed components or a runtime installed were not viable alternative or not useful.
However, I would argue that part of the reason that Bash scripts are frequently used is that Bash is widely available and installed by default.
In such environments where Bash is installed by default frequently Perl is also installed by default. Thus it might be a suitable alternative to Bash depending on the purposes of the script.
https://www.perl.org/get.html
https://stackoverflow.blog/2022/07/06/why-perl-is-still-rele...
Raku (Perl 6) is also around, but was not widely adopted:
https://raku.org/
No one who remembers the 90s-00s (and how incredibly helpful Perl was, until those other languages at its lunch) has any "hate", as such for Perl. Even its staunchest critics (best as I recall) still had a strong baseline respect for what it was able to accomplish, and how it moved the craft as a whole forward.
I disagree that it still makes for a good choice, for the simple overriding reason that (whatever one thinks of it) it has objectively become a niche language, and a will continue to remain a slowly fading one at that. In fact it's been solidly on that course for close to 20 years now.
As such it's hard to think of a good argument for bringing it into your toolchain in a big way, absent some very good reason (like some specific tool or subsystem based on it).
That said I don't mind your sticking up for it, and there's no reason you should be downvoted for doing so.
Perl 5 is a camel:
https://en.wikipedia.org/wiki/Programming_Perl#/media/File%3...
It is a smelly, sturdy beast that requires minimal resources and can get you through the desert.
OP asked: "What are the most interesting, alternatives for simple scripts."
As you've stated, Perl 5 has served as an alternative to shell scripts for nearly 30 years. It may not be the best choice for every use case, but I have seen several questions on HN where people need an alternative to Bash and Python, but have no idea how easy the problem could be solved with a Perl one-liner.
All too frequently Perl is dismissed by people who are ignorant of it because it is trendy to 'hate on' it.
You are correct, but this is HN.
It's a popular "command" language. PowerShell's language is another "command" language, but Bash is more popular than PowerShell due to its vastly longer history and Unix's superiority as a platform for technical work compared to Windows.
Other "scripting" languages (like Python or JavaScript or Ruby) are not drop-in replacements for Bash or PowerShell. You can do with Python what you should do with Bash (such as a nightly system maintenance script or a script that installs a program on your system), but it will be more work (assuming you've already paid the not-insignificant upfront cost to learn Bash). Bash directly interfaces with the system shell in ways Python cannot and was not meant to. Python's a general-purpose scripting language, meant for general work on any system, while Bash was designed to be your gateway to the Bash shell (the terminal) for your Unix system, same as PowerShell for Windows.
Arguably, on the flip side, that's why it's so horrible for general purpose work compared to Python. Making a Space Invaders game in Python? Great. In Bash? Morbidly cool but horrible.
There are Python-based shells for Linux, for example, but I don't think Python can ever be as ergonomic of a "command" language as Bash since they're two different paradigms. They just happen to both output script artifacts.
Which is precisely the sticking point with bash.
The learning curve to do bash even adequately right, while perhaps not too steep - is definitely quite slippery. And (as you apparently point out also) once you've done the time (and misery), it unfortunately does not yield anywhere near to productivity benefits in other domains, compared to the the other languages mentioned.
Haha, yep.
I think a good metric for the difficulty of a technology is how awful StackOverflow answers and code snippets are. Bash, C, and CMake are the worst in my experience, in that order. :p
> it unfortunately does not yield anywhere near to productivity benefits in other domains, compared to the the other languages mentioned.
I assert that this depends on what you're doing.
If you're doing general programming (e.g., making an application for end users), a general purpose language will be better than a command language.
If you're doing system programming (e.g., an automation or installation script), a command language will be better than a general purpose language.
Bash is Unix's command language. If I rewrote my maintenance scripts in Python, they'd be these awkward wrappings around Linux commands that Python naturally treats as second-class citizens. My Bash scripts are much better to work with, and I feel more productive with it in systems work than Python. It's awkward and weird, but that's probably inherent to being a useful and compact command language.
But if you never ever use the CLI, then scripting in bash is going to be more alien to you.
But, ah, no.
Exactly.
> [...] And not often in a better way.
Compared to a fully-fledged programming language? I sure hope so.
> What are the most interesting, alternatives for simple scripts.
For simple scripts, there's no better alternative. ZSH has some features that you wouldn't find in bash at the time.
The safest approach is to use bash or shell (/bin/sh). For programming languages golang binaries are portable, that's the big advantage over python, ruby, perl, etc.
When you need to perform advanced error checking, etc. makes sense to use a programming language. For simple operations bash is great, assuming one understands how process ripping works, signal propagation etc. works.
Things like python, perl, etc are all "nicer" programming languages, but have a lot more issues with distribution. Bash (and related shells) is just a bunch of syntax around setting up environment variables and running commands, which are just executables.
It is very much worth a read.
Besides the idea that command line programs are written primarily for the purpose of being composable, and that they follow a philosophy that makes them easy to work together, I think there are a few other pieces of secret sauce.
The lack of boilerplate is a major advantage. Low boilerplate bash pipes means input/output to/from another program is trivial. Exit code behavior as well as error behavior (output to stderr) further enhances the ease of composing individual tools to do something that would take a while to write a script to do.
The power of bash is that just about anything is trivial if it has the form:
Bash can be an optimal tool for just about anything that does not require "joining" different types of data or "branching" behavior.Once you invoke branching, joining, or complex data structures/formats, bash is no longer the right tool and python is probably the right one (although if ruby had come first, it is actually probably better for relatively simple scripting).
As a contrast I have been experimenting with using Lua and lua-posix to write a wrapper around ffmpeg. Just some batch encoding tasks nothing too complicated. The logic is easy, spawning the main encodes isn't difficult, reading the json output of ffprobe is hard.
Perl has a reputation, and isn't always available. Python isn't always available either and has the 2 vs 3 problem still (maybe not for much longer).
Many scripts are super simple, or at least start that way, so something that starts as just a list of commands to run is a better interface; but it gets unweildy if you need deeper logic and nesting of things. Such is life.
Mere `python` will remain ambiguous for years whether you'll get 2 or 3, but explicit `python3` doesn't have that problem.
I tried Ruby instead and it's nice but not enough of an improvement over bash for me. I tried Julia which has nice support for shell but the JIT compilation was annoying so I dropped it.
Currently I'm trying Nimscript, which is ok but example code is sparse, docs unfriendly, and the language is hostile to tabs and it has noisy output that you have to disable. Overall it's not pretty but workable so far.
Before you downvote me for insulting your fave language, he asked for opinions, and that's what I wrote.
This was a pain point for me too. With Julia 1.9 (now in release-candidate), the compilation results of every project is stored and reused, and I've heard that's making a lot of difference. If you're not changing the script too often, you should rarely see compilation latencies with 1.9+.
*nix shell is an interactive, concatenative string language with transparent file system access and binary loading capabilities. It's fairly unique among languages and very good at what it does. I would hate to have to write a python script or C program every time I want to rename 1000 files or repack an archive or execute a few programs in sequence or conjuction.
Much can be accomplished with 1 liners that are easy to type. That can't be done with something like Python.
Is it -0 --null, -zero or -z?? Who knows? And every app has a different option. Only a grizzled old greybeard would remember.
In some cases you really need the \0 delimiters for safety, but a large portion of safe scripting in shells is merely about handling arrays of strings, without joining nor splitting them on whitespace. bash does have arrays and "${array[@]}" syntax but it's pretty horrible (and needs the `shellcheck` linter to keep right). Some more modern shells e.g. `fish` do much better on this.
Unix (and later the internet), by enforcing "narrow waists" [1] like a flat stream of octets for all communication, is inherently polyglot. You can have richer data types inside programming languages, and indeed Python, JS, Rust etc. all have vibrant ecosystems of packages with rich internal APIs. But at some point you want to interface software written in widely different languages, and Unix encourages a particular style of command-line interface which is "dumber" — array of arguments, flat file(s) I/O — but is easy to compose across languages.
Therefore, whatever you do in "better" languages, there remains a need for a glue layer whose main job is not doing computation itself but invoking external processes. There is tons of arguing about the threshold — whether a particular task is better expressed inside a "rich" language or by plumbing together commands — but it doesn't change the need for a good shell language to exist.
Now, is bash a great shell language? NO. It's a pragmatic choice for historic reasons. One day we'll do much better. [2]
[1] https://www.oilshell.org/blog/2022/03/backlog-arch.html [2] https://github.com/oilshell/oil/wiki/Alternative-Shells