浅谈unix之美
在『高效能程序员的七个习惯』里,我谈了 unix 的哲学。这里举个例子:
$ docker ps -a -q | xargs docker rm
先解释一下,docker ps -a -q 列出了系统中所有container的id,docker rm 根据id删除某个container。但是我要删除所有的container怎么办?难道要我再做一个新的命令 docker rm-all,或者 docker rm --all?
两种方式都不优雅。其实我们需要的就是把两个已有的功能组合起来使用。怎么办?
unix的pipe和xargs就是为此设计的。pipe创建了一个管道,允许左右两端的进程通讯;xargs将管道左边的进程的标准输出重定向到管道右边的进程的标准输入,任其处理。用人话来说就是,pipe好比水管一样,xargs好比阀门,控制让水从一头流向另一头。
乍一看,本来我要实现一个程序,现在反而多实现了两个,有点不经济啊?其实这就是unix的哲学 —— 做一件事,做好它。
pipe只关心水管做得结不结实,xargs只关心水流是不是正确从左边流到了右边,docker ps -q -a 只显示container id,docker rm 只做删除一个container。四个彼此互相并不认识的命令,凑在一起,优雅地解决了一个问题。有没有乐高积木的感觉?
复杂是软件的大敌,当你把一件事情做得足够简单的时候,你犯错的机会就少了很多,程序的健壮性就得到了保证。简单还有一些其它的美妙的副作用:
- 灵活,可以使用在很多你想象不到的场景
- 高效,你可以进行彻底地局部优化,而不用担心制肘
- 可伸缩,因为只做了一件事,使用者可以按照自己希望的方式将其并行或并发运行
有一个叫minecraft的游戏,游戏中你只能干一件事,搭积木(不好意思,我还真没玩过,只听说过)。你的基本素材就是方块。就是这样一个简单而又开放的游戏,造就了许许多多的奇迹。题图中的企业号(To 非星迷,请脑补星际迷航)就是一群天才一点点用一个个小方块搭建成的。
简单 = 无穷无尽的想象
复杂 = 思维禁锢并僵化
回到unix。
几天前工作的时候要解决一个问题:两个进程本来在同一台机器上用unix socket通信,后来其中一个进程转到了另外一台机器,两者还要通信,怎么办?
我们当然可以打开源码,将unix domain socket转成tcp socket进行通讯。
但是,如果其中一个进程的源码不受你的控制怎么办?
想想unix的解决之道吧?