small pixel drawing of a pufferfish j3s.sh

thought/write-posix-shell.html

#!/bin/sh

                 what is shell?

  most people in tech are familiar with shell scripts.
  but shell is a language!

  ...

  shit. actually. wait, let me rephrase-

  most people _use_ shell.
  most people _avoid_ shell.

  but mostly

  most people  _hate_ shell.

  but should they?

        /\
       {.-}
      ;_.-'\
     {    _.}_
      \.-' /  `,
       \  |    /
        \ |  ,/
     [0] \|_/


           why do people hate shell?

  arcane syntax
      shell's syntax is cumbersome and arcane
      because it was invented around the time
      people thought lawn darts were a good idea.

  confusing error handling
      in python there's try/except. in golang, errors are values.
      in shell, errors sorta just happen in insane ways.

  hard to maintain
      when shell grows beyond a few hundred lines
      or so, it becomes impossible to maintain.

  unique and weird
      since shell has no "canonical form" shell scripts
      can look wildly different depending on the author,
      which furthers confusion.

  perception
      in the tech industry, people often look down on
      shell scripts as tech debt / lame, devs are
      often incentiviced to use hotter, more exciting things.


           so why use shell at all?

  simply: because shell is an insanely productive language.

  in fact, i believe that shell is the *most* productive language.

  in terms of time + brainpower spent to produce a result, shell can
  do in 10 seconds what would take much longer in any other language,
  because shell is optimized for speed, instant feedback, and is enhanced by
  many years of easily searchable knowledge. shell is also ubiquitous
  and accessible almost anywhere you need it.

  people often think that they're not capable of doing certain work as
  quickly as i can. but here's my secret: i'm dumb as hell.

  i just know a little bit of shell.


                 [2] .----.   @   @
                    / .-"-.`.  \v/
                    | | '\ \ \_/ )
                  ,-\ `-.' /.'  /
.................'---`----'----'


             bash me in the head

  like human languages, shell has many dialects. there's the
  common bash and zsh. let's see. there's also ksh.
  oh, and dash.
  and fish.
  csh.
  mrsh.
  tcsh. pdksh.
  the list of shell dialects goes on and on forever
  like a slimy snail

  each shell dialect has varying levels of compatability
  with the others. for example, imagine writing
  a typical bash shell script using the only to
  realize that it won't run inside of your alpine
  container, because alpine uses dash.
  imagine writing a shell script on macos, only
  to realize that it won't run on linux.


  when people write shell, they will often say things
  like "i'm writing bash" or "i'm bash scripting"
  they say this because bash is the most
  common shell dialect.

  (bernie sanders voice) let me be clear:
      if you write shell and use some bash features,
      you're writing shell in the bash dialect.
      if you happen to not use any bash features,
      then you're writing plain shell.

  the reason i'm being pedantic about "bash" is because
  i believe that most people should only learn and write
  a single dialect of shell: posix shell

  this opinion is not very widespread, but i think that
  it should be.

  let me explain


          *eternal sunshine of the posix shell*

  describing posix shell is simple. it is shell written
  in accordance with the posix specification.

  the bad news is that the posix specification is documented
  on the worst website i've ever seen[1], which i fully blame
  for posix shell being unpopular.

  the good news is that if you write posix shell, there are
  huge benefits.

  posix shell is compatible:
      it'll run on debian,
                  on openbsd,
                      in an alpine container,
                          on macos! illumos! even fucking AIX!

  posix shell is defined:
      the posix spec fully defines how shell works.
      it defines every command, every flag, and every builtin
      function. it defines how loops work, how case statements
      ought to look, yadda yadda.

  posix shell is pretty small:
      if you enjoy reading technical specifications for
      fun (aka: if you are a massochist), you might read
      through the posix spec - it'd only take a day or two.

      or, you might just read the parts of it that
      apply to the problems you solve, and piece it together
      over time - that's what i did.

      this feels bad:
          running arcane shell commands copy&pasted from stackoverflow,
          having them work, and being like "uhhhh wut" and moving on
          because "shell is such a weird little guy"

      this feels good:
          running posix shell commands that you reference directly from
          the specification, knowing that they'll simply work
          everywhere on everything for eternity.

  posix shell is eternal:
      imagine posix shell as the "standard library of shell"
      the concrete foundation on which you stand. posix shell
      was first defined in 1992, and has remained largely the
      same since. it is an important language that has lasted
      30 years, and is very likely to last 30 more.


             /------------------------------\
             |                              |
             |          omg!                |
             |  posix shell is amazing!     |
             | i wanna use it everywhere!   |
             | i wanna go use it RIGHT NOW! |
             \------------------------------/*
                                              *
                                               *
                                                🤔 <-- you

  slow down there you son of a gun!!
  yes, posix shell is amazing, but it's also very constraining.

  consider this sentence:
    "arrays do not exist in posix shell"

  ...

  "NOOO!" you shout, because you like data structures a LOT
  "now THAT'S a good reason to use bash! bash supports arrays!"

  absolutely not!

  i believe that you should use shell if your problem is:
    - small and scoped (~200 lines of shell or less)
    - unlikely to increase in size and scope as time goes on
    - not very complex

  if you breach the shell complexity ceiling, you should stop
  immediately and use python or rust or whatever instead.

  here are some simple ways to tell if your problem is too complex
  for shell:

  1. if you suspect that a shell program could be more
     than ~200 lines at any point in the future

  2. if your shell program needs arrays, structs, maps, or any
     other complex data structure

  3. if you need to do error handling, or if the program
     must be very reliable - use a programming language.


               when should i use shell?

  it depends! i use shell every day, and i suspect that
  many other people could benefit from using it every
  day as well. i never regret learning more about posix
  shell.

  here are some great use-cases:

  posix shell inspo:

    dylan araps is the person who first inspired me to
    dig into posix shell, and his projects[3] are
    absolutely worth a browse.

    drew devault often promotes posix shell, and has used
    posix shell to write a git client called shit. [4]

    look at pa[5], a posix shell password manager that i
    wrote.

    check out my dotfiles[6], which contains a ton of
    little posix shell scripts that i use for all sorts
    of things


  now get out there and write some fucking posix shell god damnit!


[0]: https://archive.ph/KLpzo
[1]: https://archive.ph/higTn
    sidenote: if anyone out there wants to make a posix shell
              website that doesn't suck absolute ass, let me know.
[2]: ascii snail by Hayley Jane Wakenshaw
[3]: https://github.com/dylanaraps
[4]: https://git.sr.ht/~sircmpwn/shit
[5]: https://github.com/biox/pa
[6]: https://git.j3s.sh/dotfiles/tree/main/bin