For the first few years of my career, I didn’t know how to tell my computer to do things. I could kick off a few commands from the terminal – run those tests, install that dependency, start that container, ssh to that machine – but I was limited to running simple commands one at a time. My terminal was the world’s worst GUI, and I thought that the shell was the way to start programs that didn’t have application wrappers.

At a fundamental level, I wasn’t able to tell my computer to accomplish anything that involved logic or stitching together multiple programs like:

  • Do one thing and then do another
  • If a command fails, log out an error message
  • Kick off a program when the computer starts
  • Run two commands at the same time
  • Loop through all of the files in a directory and take an action on each one
  • Use the output of one command as the input for another