On the Beauty of Unix
In “The Seven Habits of Highly Effective Programmers,” I discussed the Unix philosophy. Here is an example:
$ docker ps -a -q | xargs docker rm
First, a brief explanation: docker ps -a -q lists the IDs of all containers in the system, and docker rm deletes a container by ID. But what if I want to delete all containers? Do I have to create a new command, docker rm-all, or docker rm --all?
Neither approach is elegant. What we actually need is to combine two existing capabilities. How?
Unix’s pipe and xargs were designed for exactly this. pipe creates a pipeline that lets the processes on either end communicate; xargs redirects the standard output of the process on the left of the pipe to the standard input of the process on the right, which is free to process it. In plain English, pipe is like a water pipe, and xargs is like a valve that controls the flow of water from one end to the other.
At first glance, I originally needed to implement one program, but now I’ve implemented two extra ones—doesn’t that seem inefficient? In fact, this is the Unix philosophy: do one thing, and do it well.
pipe cares only whether the pipe is sturdy enough; xargs cares only whether the water flows correctly from left to right; docker ps -q -a only displays container IDs; docker rm only deletes one container. Four commands that know nothing about one another come together and elegantly solve a problem. Does it feel like LEGO bricks?
Complexity is the great enemy of software. When you make a thing simple enough, you greatly reduce your chances of making mistakes, and the robustness of the program is assured. Simplicity also has some other wonderful side effects:
- Flexibility: it can be used in many scenarios you never imagined
- Efficiency: you can perform thorough local optimization without worrying about constraints
- Scalability: because it does only one thing, users can run it in parallel or concurrently however they wish
There is a game called Minecraft, in which you can do only one thing: build with blocks. (Sorry—I really haven’t played it; I’ve only heard of it.) Your basic material is cubes. Yet this simple and open-ended game has produced countless wonders. The Enterprise in the title image (for non-Star Trek fans, please imagine Star Trek) was built block by block, little by little, by a group of geniuses.
Simple = endless imagination
Complex = imprisoned and rigid thinking
Back to Unix.
A few days ago at work, I had to solve a problem: two processes had been communicating on the same machine via a Unix socket, and then one of them moved to another machine. They still needed to communicate—what to do?
Of course, we could open the source code and convert the Unix domain socket into a TCP socket for communication.
But what if you don’t control the source code of one of the processes?
Think about Unix’s way of solving things.