Hacker News new | past | comments | ask | show | jobs | submit login
Babashka – A Clojure for the grey areas of Bash (github.com)
238 points by tosh 61 days ago | hide | past | web | favorite | 65 comments

Interesting trivia on the name (from Wikipedia):

> Some English speakers use the word "babushka" [бaбушка] (the word for 'grandma' in Russian) to indicate a headscarf tied below the chin, as still commonly worn in rural parts of Europe.

However the author should be aware that most people would interpret "bab(a|u)shka" as "grandma" and not as a scarf. Which works too, I guess. Personally, I always think of a https://en.wikipedia.org/wiki/Matryoshka_doll (which is also sometimes called babushka) when I see this word...

I also thought this was about a grandma who would lovingly guide me through the hard parts of bash... which honestly still makes more sense to me than the headscarf ideology.

It's very strange to me that someone would keep using this word in those contexts even after being told that this isn't what it means. It's almost like "babushka" to the English-speaking mind is stand-in for "funny sounding Russian word". It does have a rhythm that sounds a little whimsical in English. It's also usually pronounced in English with stress on the wrong syllable. [Should be bábushka.]

It's not at all unusual for loanwords to get different meanings when they are adopted. Wikipedia gives this lovely example:

The English word Viking became Japanese バイキング (baikingu), meaning "buffet", because the first restaurant in Japan to offer buffet-style meals, inspired by the Nordic smörgåsbord, was opened in 1958 by the Imperial Hotel under the name "Viking".

While we are on the subject of Russian words with "bash" in them, I offer "barabashka" to whomever's interested. (It is one of the names for https://en.wikipedia.org/wiki/Domovoy)

Or even more simply, "Bashka", which means "head" in slang.

I interpreted as "grandma" as well since it's a super popular Russian term on the internet (eg: YouTube) nowadays.

I think Babashka (bb) takes important lessons learned about how Clojure grew and applies them well. Piggieback on the tools and libraries already in place and just provide a simpler, more uniform syntax and build in portable standard library (in Clojure and I assume in bb just really need to use maps and arrays). Clojurescript (CLJS) does this beautifully and bb is setup to achieve the a similar success story. CLJS is not perfect (see https://twitter.com/royalaid/status/1224830807807676417 for an example of the runtime leaking through) but it is wonderfully pragmatic and incredibly productive and hope to see bb become to bash what Clojure is for Java and CLJS is for JS.

Also noteworthy, Babashka is powered by the Small Clojure Interpreter [1] (same author) which has additional applications. Both are very promising!

[1] https://github.com/borkdude/sci

Why are many of the examples so easily solved using other much simpler methods? Could they not come up with some actual reasonable use cases?

>ls | bb -i '(count input)'

ls | wc -l

>bb '(vec (dedupe input))' <<< '[1 1 1 1 2]'

send your input to `uniq` for chrissakes

>ls | bb -i '(filterv #(re-find #"README" %) input)'

just `ls * README * ` (there shouldn't be spaces around the * s but HN formatting doesn't like me)


come on, honestly.

https://github.com/borkdude/babashka#gallery has some more compelling examples. When I wrote https://github.com/cldwalker/clj-clis/blob/master/clj-github..., I found babashka to be useful because it provided a more readable and thus maintainable way to parse cli options and parse a json response

I guess the examples are so simple so that every bash user can translate them easily.

Who cares? That doesn't do a good job showing why this software is useful. At first glance it makes it look like everything is just more complicated.

Do you speak Clojure?

If not, this isn't for you anyhow.

Genuinely curious, what advantage does Clojure provide in this context that other tools don't handle as well or at all? I agree with the GP post, none of the examples listed show that this tool is superior to what bash and other GNU tools already provide.

In other words, if I don't speak Clojure, why should I learn? This project hasn't convinced me it's worth it yet, but maybe it is?

Author of babashka here. This tool is intended for people who find Clojure easier to work with than Bash because of familiarity or whatever other reason. If you're not one of them, that's fine, just use Bash.

There is no reason for not using more compelling examples.

What other things that exist offend you?

I think you accidentally replied to the wrong comment.

I haven't used this tool, but I imagine using the "-f" option to run a script could be much nicer than writing a bash script. Bash (or any Unix shells) aren't really known as great environments for tasks that don't fit comfortably on a single line.

I think it's for anyone who writes intermediate shell scripts. I don't "speak" Clojure but I'll be giving it a try sometime.

Reminded me of Closh (https://github.com/dundalek/closh), which is a Bash-like shell based on Clojure. Both Babashka and Closh runs Clojure code directly from shell.

Aside from the obvious problem that the babushka is the grandmother herself, not the clothing she traditionally wears, what on earth do headscarves have to do with coding? How is this metaphor intended to work?

Author of babashka here.

The original tagline was "a sprinkle of Clojure for the command line". A user of babashka commented that this tool was exactly right for him to cover up the grey areas of bash (bash constructs he could not remember the syntax for). If you picture bash as a grey woman and Clojure as the headscarf to cover her grey hair, the metaphor might start to make sense.

Aha, that makes more sense - thank you for the explanation.

I've been out of the Clojure ecosystem for some time now -- has GraalVM solved the slow start problem? I remember the 1-2 second start up time being a deal breaker for many applications.

You can make CLIs with Clojure + GraalVM that have instant startup. Babashka, a Clojure interpreter written in Clojure, is one of them.

This is a nice writeup of someone diving into GraalVM + Clojure at work:


as a sidenote, the README contains two really bad practices, pipeing the output of curl into bash (running arbitrary code that can do whatever it wants), and parsing ls.


`curl X | bash` provides _more_ transparency than most other usual methods of software distribution, as I can always inspect X, which is usually a simple, self-contained script.

In contrast, running code from an unaudited source (GitHub, NPM, etc.), or executing a binary from some random website, all less transparent yet just as dangerous, but for some reason raise way fewer eyebrows.

Those methods of installing stuff suck too, and its not like you have to pick one of the three...

The main problem isn't malicious code, you can review the script after all, the main problem is the app making unwarranted assumptions about your install/distribution, then breaking things in the process.

You can only be sure of what you're running if you download it first, examine it, then run what you downloaded.


"You can only be sure of what you're running if you download it first, examine it, then run what you downloaded."

What if, before "run what you downloaded", first perform a dry run and observe it while it is running.

   set -x
   curl https://example.com/setup.sh | bash -n
   set +x
-x Execution trace

-n Read commands but do not execute them


Correction: -n and -x are obviously mutually exclusive. Have to use -v instead.

   curl https://example.com/setup.sh | bash -vn
As for trying to hide commands from an execution trace, it is not possible to hide the set +x command.

   cat > 1.sh
   echo visible
   set +v
   set +x
   echo hidden >/dev/null

   cat 1.sh | bash -x

  + echo visible
  + set +v
  + set +x
One can syntax check setup.sh before downloading it with -vn (or perhaps shellcheck). After downloading and reading it, one can observe it while it is running with -x.

The truth is that people download and run shell scripts without reading them all the time. For example, how many people installing software packaged with configure scripts actually read the scripts. (Except in the event they do not work.)

a script can just set +x before doing anything else, and then fake output.

No, this doesn't work.

Why not?

As to parsing `ls`:

Bash scripting is incredibly powerful but also terribly broken with horrible edge cases. E.g. if syntax, bash quoting, -print0, parsing strings with regexps... It's near impossible to build sound applications with bash.

Parsing output of almost any program breaks at _some_ point: https://dwheeler.com/essays/fixing-unix-linux-filenames.html

You need to know what data you are dealing with when writing shell scripts. bb does not aim to fix that. Just gradually improve.

But parsing ls (with no arguments) is just stupid when there is a safe alternative that already exists and is shorter.

There was a recent blog post that got a fair bit of traction here on HN that talked about why this isn’t really that big of a problem in and of itself:


HN discussion: https://news.ycombinator.com/item?id=21490151


(All: the link is to a music video).

At least warn us that we're clicking into something irrelevant and silly if we follow the link.

    $ bash <(curl ...
Seeing this in a README immediately indicates that the author has no idea what they're doing security-wise, and that I probably shouldn't trust their project.

I've never understood why people think this is somehow less secure than downloading a binary blob you can't inspect and running that instead.

I don't think I've ever downloaded and executed a binary blob. Either use a package manager or compile from source, it's really not that hard.

How is compiling and executing source you didn't examine any more secure than executing a bash script?

It's not like package managers are immune either: https://www.theregister.co.uk/2018/11/26/npm_repo_bitcoin_st...

Not necessarily ... there are many high profile projects that recommend installation this way. NodeJS and HomeBrew come to mind. Unfortunately it's sort of becoming a standard practice these days.

Pretty sure even like homebrew does the same thing, chief

whats the issue here? (genuine question) besides having to trust the author? and what installation methods do you recommend for cli tools?

looks like the author also provides package manager installation on further reading of the readme. I'm still not quite seeing the issue with the curl to bash, I'm trusting the author by running their tool, regardless of the installation method. And I could always download the script first to check it right?

ah I see, the greater risk of mitm attack due the script not being hosted by a package manager, fair enough.

Why? If you really want to do scripting in lisp, why would you not just use guile?

This is just embracing complexity when scheme is a perfect fit, and already exists in multiple ways in the domain.

Did Gauche stop existing?


Oy please. Some Lispers are stuck in the past with their ivory tower ideals, saddened that nobody wants their favorite flavor of Lisp anymore. Why can't you embrace the fact that Lisp just like any other idea does have right to evolve and change?

> Did Gauche stop existing?

Out of all the five people who ever heard about it, three probably stopped using it and for the rest, it may just be like it never existed - they've never heard about it.

Clojure on the other hand somehow managed to become third most popular JVM language and very popular alt-js language. Out of all PLs that can be considered somewhat esoteric, Clojure today is the most vibrant - it has more books, podcasts and conferences. More than Elixir, OCaml, Haskell, Elm, Purescript and even Rust.

Very few people used Guile, even before Clojure got some spotlight. So instead of whining why can't you be happy for the fact that people still want to use Lisp in 2020 at all?

So your argument is that I'm somehow a lisp fanatic and I should be happy that at least one lisp made it into the current fad?


Because I'm a clojure programmer, not a scheme programmer. While I think scheme is nice, I know clojure well and really like much of its design. So, for me, if someone had said "hey, try this guile thing instead of bash" I'd pass it over like the many other projects I pass over all the time, but this interested me because it lets me use a language I know and like.

Why use two languages with similar semantics when you can use one with nearly identical semantics? It might make sense for Emacs Lisp because there are things you’d do differently in a modern Lisp (Guile Emacs sounds great to me), but Clojure is already modern. Interface costs, both human and technical, aren’t free.

Man, I'm pretty up to date on things but I admit this is the first time I've heard of Gauche. Seems like a pretty mature project too what with the 907 page PDF manual.

let them use clojure if they want to who cares

Because one day you go to look for minimal cli programs and find githubs littered with "minimal dependencies, only nodeJS!".

It's madness. There's already several much better tools people should be using for these domains, but they seem to insist on importing their massive and bloated toolchain in instead.

Why even bring that up for a Clojure project that compiles down to a single native binary? This is not Node.

The materials that go into that binary which don't come from the project itself are external dependencies.

There is a dependency on a Java VM implementation, GraalVM, and on a Small Clojure interpreter. That looks Node-ish to me, regardless of the application deployment model.

GraalVM has some kind of updater, "gu", that's looks reminiscent of npm:


> The materials that go into that binary which don't come from the project itself are external dependencies.

Not sure what you're on about... any piece of software is going to be composed of smaller pieces. What's wrong with that?

> There is a dependency on a Java VM implementation

Only for developing it.

> GraalVM

GraalVM is many things. This is compiled using GraalVM Native Image which compiles JVM bytecode into a native binary executable. There is no JVM hidden away in that executable either.

> and on a Small Clojure interpreter

The fact that it uses a a library (by the same author) for interpreting Clojure - what exactly is the issue here? If he didn't separate that into a library it would be fine, but the moment it's modular it's an issue to you?

> GraalVM has some kind of updater, "gu", that's looks reminiscent of npm:

GraalVM includes a command-line utility and that means it has the NPM cooties...?

I don't know what planet you come from, but on my [primitive] planet people haven't yet learned how to build working software with exactly zero dependencies.

Why? If you really want to do scripting in scheme, why would you not just use TinyScheme?

This is just embracing complexity when R5RS is a perfect fit, and already exists in multiple ways in the domain.

Did scsh stop existing?


Tinyscheme doesn't have baked in and complete posix/libc/etc bindings.

Also you'd have to say R5RS -> R7RS is somehow a fall into complexity which makes absolutely no sense.

Scsh hasn't been updated for over a decade.

I appreciate the satire but I think compared to something like Guile, no one has answered what this does better beyond personal preference. And honestly, I don't see that alone as a good justification.

I could have a preference for using Matlab to bootstrap embedded devices but that doesn't make it a good idea.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact