Why should you read 1984's "The UNIX Programming Environment" thirty-eight years after it was first published? Why did I read this book? (Well, I am an unrepentant fan of bash.) Is it even relevant anymore? (Yes.) Why should you read it?

In order to understand where we're going as an art, it's important to know where we came from. It's 2022 and I still SSH to boxes, edit files using vim, and write bash scripts. To be honest, sometimes it feels like the only that's changed in the fifteen years is the amount of YAML I have to wrap my bash in.

So yeah, as the Palmolive commercial says, "You're soaking in it!" This 1984 book remains relevant: most tools we use are either from this era, reactions to these tools, or reactions to the reactions. Tools written outside of this conversation exist and can be effective, but generally they feel slightly off. They don't integrate with other tools like they should.

Writing tools that coöperate fluently with each other gives you an opportunity to leverage network effects; to make all existing tools more useful with your tool.

So. That all being said, let's talk about the book itself. "The UNIX Programming Environment" is short and sweet, clocking in at a little over 250 pages. Each chapter introduces a new topic, explores how it interacts with topics from prior chapters, then raises issues for the next chapter to resolve. The book starts with the key innovations of the UNIX operating system and builds from there to illustrate a "blessed path" for program development:

  • The filesystem
  • Using the shell
  • Filters
  • Shell programming
  • The process environment: using stdio
  • System calls
  • Program development
  • Document preparation

Some chapters are more relevant to contemporary readers than others. In particular, while the section on document preparation is interesting from a historical perspective, unless you're writing man pages by hand, you probably won't have occasion to use the tools described there.

It's worth noting at this point that this book wasn't written during the early development of UNIX. Rather, this book was written 11-15 years later, when UNIX had already escaped containment at Bell Labs and was rapidly growing in popularity.

Quoth the book, in an example given in a late chaper:

John Lions taught the 6th Edition UNIX kernel in an undergraduate OS course at UNSW. In notes prepared for the class, he wrote, "the whole documentation is not unreasonably transportable in a student's briefcase." (This has been fixed in recent versions.)

(You can expect this level of self-effacing, dry humor throughout.)

The section on program development gleefully sings the praises of yacc, sharing the fascination with parsing so common in texts from this era. The C code listings are somewhat less directly applicable today than the shell listings, but the progression from "using the shell" to "using filters" to "programming the shell" to "writing the program in C with system calls" does an excellent job of illustrating the third point from the oft-quoted, frequently-truncated UNIX philosophy. I include the full treatment of the philosophy from the book itself:

First, let the machine do the work. Use programs like grep and wc and awk to mechanize tasks that you might do by hand on other systems.

Second, let other people do the work. Use programs that already exist as building blocks in your programs, with the shell and the programmable filters to glue them together. Write a small program to interface to an existing one that does the real work, as we did with idiff. The UNIX environment is rich in tools that can be combined in myriad ways; your job is often just to think of the right combination.

Third, do the job in stages. Build the simplest thing that will be useful, and let your experience with that determine what (if anything) is worth doing next. Don't add features and options until usage patterns tell you which ones are needed.

Fourth, build tools. Write programs that mesh with the existing environ- ment, enhancing it rather than merely adding to it. Built well, such programs themselves become a part of everyone's toolkit.

I invite you, dear reader, to make a comparison to pithier, widely-known Doug McIllroy version. The book's version of the philosophy resonates with my experiences as a professional programmer for the last sixteen years. These are words to live by!

My goal in writing this review —other than to defend an otherwise indefensibly wanton habit of purchasing classic Computer Science textbooks from my local used bookstore— is to nudge you, dear reader, into leafing through this book, perhaps on a lazy day off. The UNIX Programming Environment conveys the enthusiasm and laughing regret of folks who've worked within a particular moment in computer science. It's a great jumping-off point for future research, while connecting the dots between many of the disparate tools you use every day.

So, I leave you as the book does, with an aside about ed. One of the most interesting things I learned from this book (aside from the fact that stdin is the result of open("/dev/tty"), and stdout is the result of dup(1), so you can write output to stdin) is the relationship between ed, grep, and sed. You may be aware, as I was, that grep was derived from ed; but I was surprised to find that grep had wayward siblings: gred and gres -- all derived from the ed incantation, g/re/*.

Eventually all of the variant commands were wrapped into a successor program, sed. Where this becomes useful for me: my editor, neovim, descends from vim, which descends from vi, which descends from ex, which descends from ed. My muscle memory for my editor translates directly into using sed! And likewise, everything I learn about sed carries back into my editor.

Network effects are powerful!