DEV Community

Cover image for Bash is a terrible as a programming language, but what's the alternative ?
Jean-Michel 🕵🏻‍♂️ Fayard
Jean-Michel 🕵🏻‍♂️ Fayard

Posted on • Updated on

Bash is a terrible as a programming language, but what's the alternative ?

I believe in self-compassion so I have a personal rule

Never write a shell script that is more than 5 lines long.

Let's bash Bash

I am on the record to saying that there is no programming language that is never worth learning

Bash is the exception. It's programming stuck in the stone age. No real functions. No argument names. No types. No data structure. No unit tests. No dependencies management. I need to google every time I want to do something basic like a for loop.

I like it when Homebrew or Gradle or whatever allow me to bootstrap their thing with a complex shell script. Because they went through the pain of writing and maintaining their shell script.

But otherwise, my advice is to give up.

But what's the alternative ?

If things are terrible, and they are, what are we stuck with Bash ?

First, because like with every addiction, Bash's appeal is that it's easy to get started.

  1. Just take whatever you have typed in the terminal and put that in a run.sh file.
  2. Upload that to a gist and you have spread the virus.

Second because it's not clear what's a good alternative that has the same initial appeal as Bash without its many pitfalls.

That's where you come in.

What has been your experience with scripting in $favoriteLanguage ?

Top comments (96)

Collapse
 
kwnaidoo profile image
Kevin Naidoo • Edited

I do agree that BASH is hard to learn initially and not easy on the eyes but once you get used to it, it's not that bad. Why not just learn BASH and the BASH way of doing things? Instead of trying to use it as a full-blown programming language, use it rather for administrative tasks like parsing log files.

You shouldn't use BASH for complex scripts, it's meant to just perform sysadmin tasks.

Just imagine if you want to copy a large folder to a remote server:

rsync -av  somediretory  bkuser@backups-server:/backups/
Enter fullscreen mode Exit fullscreen mode

Simple one-line command. Now in a programming language, you have to "glob" and loop through files and then use some kind of module or drop to a shell of some sort.

This is how BASH is meant to be used. Plus it allows for pipping, you can use "xargs" and pipe several files in parallel to be synced to the remote server. This is 2 lines of code VS having to do this in Python or Node would take several lines more, probably 20+.

There are several alternatives like ZSH, FISH, and so on, but ultimately on a Linux/Unix system, BASH has close bindings to the OS kernel itself, thus making some advanced tasks pretty straightforward.

Python and Perl is an alternative if you prefer a full-blown language. These should be able to do most of what you can do in BASH.

Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard

When I say that bash is bad, I mean shells in general.
They are good for sysadmin tasks, when what I am doing is one program being executed after another.

But I pause and reflect as soon as I find myself using functions / if else / for loops / arguments / ...

Collapse
 
kwnaidoo profile image
Kevin Naidoo • Edited

Absolutely! I understand what you mean and makes sense. I have been thinking of writing a Python interpreter that compiles down to BASH similar to what TypeScript is for JavaScript.

It was too much work though to just scratch my own itch :-) Maybe I might look at that if there is an overwhelming need.

Collapse
 
autra profile image
Augustin Trancart

Yes for simple scripts, it's enough. Although you are comparing apples to orange, because you can call rsync in one line in python code too ;-) (well, with the import, probably 2 or 3 but well).

My problems with bash:

  • you cannot really unit test it (and yes, I have tested bats)
  • there several ways to do "if", each with their caveats and pitfalls
  • there is no real exception handling
  • there is no real functions (they are commands) and you cannot really return from them (return statement is for error code, anything other than indicating an error is a hack and will bite you)
  • argument parsing is an horror

For these reasons, anything other than trivial is really cumbersome with bash. Especially, as soon as we have arguments to a script, we should just use python and argparse for instance.

Collapse
 
hijazi profile image
Baha

I totally agree, I have read once that if your bash script is 100+ lines then it should be python.
However under 100 lines, Bash feels like a linux super power. To be able to use the linux commands like this, and yeah and I definitely won't try to use it as general purpose programming language.

Collapse
 
autra profile image
Augustin Trancart

I'd put the limit to either one of these conditions:

  • 50 lines
  • you need arguments to your scripts
  • you have to test more than trivial stuffs
Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard

I would say that Bash initially feels like a super power
And then it quickly feels like I have shoot myself in the feet

Collapse
 
nylar357 profile image
CͨoͦNᴛⷮRͬAͣ

Couldn't agree more bash has its place and it's extremely good in that place. It's easy to pick up and useful for specific jobs.

Collapse
 
steveja profile image
Steve Alexander

Disagree. rsync binary does the glob'ing *& looping, not the shell. Bashmerely collects the two string arguments and performs a fork/exec of rsync.

Collapse
 
kwnaidoo profile image
Kevin Naidoo • Edited

Yes correct, the rsync binary is doing all the work for sure. For simplicity I used "BASH" loosely, what I meant: from a developer's point of view, all you need is one line of code.

This is a simple example, there's more advanced stuff with xargs and so forth that can also be done in one line vs a programming language where you have to write multiple lines.

BASH is a Swiss army knife, used correctly it can make you very productive. I can quickly do certain tasks in my terminal without having to open an editor and write some code. For more complex tasks, Python or any other high level language is better for sure.

Collapse
 
fyodorio profile image
Fyodor

I used to engaging Node for that. You basically need only Node (which can be installed through nvm at any env via a bare curl call or something). Rich and beautiful NPM ecosystem is at your disposal. Further convenience is the matter of efforts.

But thanks for the V reference, looks interesting.

Collapse
 
cogwizzle profile image
Joe Fehrman

If you like to use JavaScript for shells I think you would like this. github.com/google/zx

I find it easier than using the build in node process utils.

Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard

I tried zx, that looks really nice thanks !

Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard

My issue is that I know the language but not the ecosystem. Browsing npmjs.org is overwhelming.
What kind of npm libraries would you use for the common tasks someone need for a CLI tool ?

Collapse
 
fyodorio profile image
Fyodor

Usually, in addition to the standard integrated Node tools, you would need something like path and child_process (or execa), that could be enough for simple stuff and working with files and trivial scenarios. If you need some nice decoration (for a team, or for pleasing yourself 😅), there are listr, inquirer, chalk, and figlet. There's much more to that, even CLI frameworks, but I prefer simpler and more granular tools.

Collapse
 
ben profile image
Ben Halpern

I find the bigger issue ends up being the sharability.

The problem with any platform is that the further you get from the thing that ships to everyone, the less you can confidently have in common with everyone else.

That's so much of the power of bash, git, etc.

Thread Thread
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard

I strongly agree, distribution is key !

It doesn't have to be bash though, if the thing is easy to bootstrap & index via npm, brew or something, I am all for it.

Collapse
 
mistval profile image
Randall

I do basically the same. Most of the bash scripts I write just invoke node to do the heavy lifting.

Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard • Edited

language = V

The idea comes from a discussion about V, a modern programming language that on paper seems almost too good to be true.

Image description

My obvious counter-argument is : why would I invest my time learning a langauge that just reached version 0.4 ?

But then I saw this

Cross-platform shell scripts in V
V can be used as an alternative to Bash to write deployment scripts, build scripts, etc. The advantage of using V for this is the simplicity and predictability of the language, and cross-platform support. "V scripts" run on Unix-like systems as well as on Windows.
V is 80% go and can be learned in a week-end.

Ok, fair enough, I would rather spend a week-end learning V than fighting to debug a dumb Bash script, that sounds appealing to me.

Collapse
 
tgkprog profile image
Tushar Kapila

A weekend to get an intro. More tobe good

Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard

This is probably assuming you are somewhat familiar with go

Collapse
 
russellbateman profile image
Russell Bateman • Edited

I have written installation scripts in Bourne (yeah, that's sh) totally 10s of 1000s of lines of code. (Because across many, varied systems where even bash wasn't a common denominator.) Very excruciating, although this was 20 years ago and there was no debugger. Obviously, I created "libraries" and other helps, but I would have preferred Python.

Collapse
 
hlship profile image
Howard M. Lewis Ship

Babashka (github.com/babashka/babashka) allows me to have my cake (write scripts in Clojure) and eat it too (fast! startup). Having a fully powered language to write even simple things in (because they never stay simple) is near ideal.

Collapse
 
togakangaroo profile image
George Mauer

Powershell is an excellently designed language which did the hard work formalizing lessons learned from bash's awfulness.

But realistically what I see emerging in the next few years, is not yet another command line scripting language. I would be pretty surprised if non-scripted interaction with the CLI in 5 years still requires people manually typing out well formatted commands piping things between utilities. I already ask chatGPT for half of the things I want to do with the CLI, I'm not sure what's to stop that from becoming much more prevalent.

For scripting in the meantime, python or powershell or another omnipresent alternative will be fine

Collapse
 
arcanjoaq profile image
arcanjoaq

language = Clojure (with Babashka)

It has a really fast start up due to the GraalVM. 😁

Collapse
 
eric_stewart_6c37bebed155 profile image
Eric Stewart

This is the answer

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I honestly believe .*sh are an amazing family of domain-specific scripting languages, and this specialisation also makes them utterly terrible outside their domain.

If what you want consists mainly in 1. running executables 2. managing their I/O then all the best tools for that job will likely be languages you wouldn't want to write an HTTP server in, and that's not a problem.

Collapse
 
ingosteinke profile image
Ingo Steinke • Edited

One of the problems making bash hard to learn is that some commands consist of special characters, so you can't even google the correct syntax. Its compactness makes it hard to read and easy to get things wrong.

Another thing is that "bash" is not only bash, but bash plus a set of UNIX tools that we will have to use anyway, with or without additional wrapper functions around them.

There are bash built-ins that differ between shells, as many users found out when some sophisticated bash scripts stopped working on Linux machines, after Ubuntu had decided to replace bash with the more minimal dash shell by default.

I used to code Perl for web development long time ago, and maybe Perl is still a valid choice for administrative tools beyond simple bash tasks. But I also see many Python scripts used instead, so maybe we should all learn Python.

But as ECMAScript/JavaScript/TypeScript already seems to run 90% of everything that I use as a web developer, why not use node/deno for local administration as well?

Collapse
 
nova38 profile image
Thomas N Atkins

Python is great for some stuff, but to replace lot of the stuff you would use bash for powershell is one of the best scripting languages I have used. Its not perfect but it produces a lot more readable scripts and it is a lot easier to find the utility function you need because of the verb-noun syntax. (Plus it is also cross platform)

Collapse
 
strottos profile image
Steven Trotter

Agree with this completely. I genuinely think PowerShell is an overall improvement but there's still so much that annoys me about it.

Whenever people offer things like zsh, fish, etc that's like putting a sticky plaster on a broken arm. It might be a bit better but it's still building on something fundamentally broken.

I also think that bash has a lot of people stuck in Stockholm syndrome, because it's great at some things people love everything it does, but everything you say is true.

I big time think there's a market for a modern decent shell but also appreciate this is genuinely hard.

Great article 👏

Collapse
 
farrellit profile image
Dan Farrell

Totally agree. Shell scripting is deceptively difficult. The syntax is arcane and handling of error conditions complex. One of its only positive is being nearly ubiquitous, but so much functionality is left to other programs you still don't have a very consistent runtime environment.

Collapse
 
thomaslevesque profile image
Thomas Levesque • Edited

Bash is a terrible language, I won't argue with you about that. However I don't think it's the worst. Batch files on Windows are much, much worse.
I tend to use Powershell now, both on Windows and Linux. It's not perfect, but it's okayish.

Collapse
 
jmfayard profile image
Jean-Michel 🕵🏻‍♂️ Fayard • Edited

language = Kotlin

Two options :

  1. Lightweights Kotlin scripts are a thing
  2. A full Kotlin project compiled to a binary executable with Kotlin native

I liked the idea of it, but right now Kotlin scripts are very niche and not quite supported.
The native toolchain is quite heavy, the compiler is slow.
Packaging is not really ready.

So right now it's better in theory than in practice, probably use something else.

Collapse
 
mindplay profile image
Rasmus Schultz

vlang.io might be interesting as a replacement - small, simple, ships as a single executable, has most of the things you need from bash, and is much easier to learn.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.