Hell: Shell scripting Haskell dialect

Hell is a shell scripting language that is a tiny dialect of Haskell that I wrote for my own shell scripting purposes. As of February, I’m using Hell to generate this blog, instead of Hakyll.1

Update: As of 3rd Oct 2024, I’m using it on various large (2k line) scripts at work in combination with Terraform and various APIs.

#!/usr/bin/env hell
main = do
  Text.putStrLn "Please enter your name and hit ENTER:"
  name <- Text.getLine
  Text.putStrLn "Thanks, your name is: "
  Text.putStrLn name

My 2024 New Year’s Resolution is to write more shell scripts in the name of automation. I’ve always avoided this because of the downsides of bash. And other problems.

Bash, zsh, fish, etc. have problems:

But, bash does have some upsides: It’s stable, it’s simple, and it works the same on every machine. You can write a bash script and keep it running for years while never having to change any code. The code you wrote last year will be the same next year, which is not true of most popular programming languages. Look at Haskell.

So in the interest of defining a language that I would like to use, let’s discuss the anatomy of a shell scripting language:

Why no module or package system? They make it harder for a system to be “done.” There’s always some other integration that you can do; some other feature to add. I’d prefer Hell to be cold-blooded software, there’s beauty in finished software.

Based on the above, I can define a scripting threshold, meaning, when you reach for a module system or a package system, or abstraction capabilities, or when you want more than what’s in the standard library, then you probably want a general purpose programming language instead.

Taking this into consideration, I opted for making a Haskell dialect6 because of the following reasons:

I made the following decisions when designing the language:

You can download statically-linked Linux binaries from the releases page. To read about the implementation internals, see Tour of Hell which is a set of slides I made for presenting Hell at work.


  1. I’m tired of issues like this.↩︎

  2. Just check out the huge list of linting issues in ShellCheck.↩︎

  3. See this blog post about code execution↩︎

  4. This excludes scripting languages like zx, which sits, unbelievably, on the nodejs ecosystem.↩︎

  5. See also: Escaping the Hamster Wheel of Backwards Incompatibility↩︎

  6. And not using some other alt. shell scripting language or using Elixir, or Oil.↩︎