linux shell小程序
凌晨三点,小程序我盯着终端里滚动的小程序日志,手指在键盘上敲下第十七个`grep`管道。小程序突然意识到,小程序这堆看似杂乱的小程序命令组合,其实就是小程序我每天在写的小程序——只不过它们没有`.c`后缀,也没有编译过程。小程序shell脚本就是小程序这么个怪东西:它不像是程序,倒更像你对着系统说话的小程序方式。
拿上周处理服务器日志的小程序事来说。两百多个文件,小程序每个十几MB,小程序要找出所有凌晨时段的小程序500错误。用Python写?小程序光导入模块和定义函数就得二十行。我直接甩了三行:
grep " 03:" *.log | grep " 500 " | awk '{ print $1,小程序 $4}' > errors.txt
两秒跑完。旁边的同事瞪大眼睛:“这算编程吗?”算,当然算。只不过你用的是系统自带的“乐高积木”,而不是自己烧砖。
shell小程序最迷人的地方在于它的“临时性”。我有个习惯,凡是要重复三次以上的操作,就写成脚本扔进`~/bin`。比如那个`clean_tmp.sh`,就五句话:删掉三天前的缓存、压缩旧日志、发个磁盘占用报告到邮箱。没什么技术含量,但它每个月帮我省下两小时手动清理的时间。这种脚本不需要注释,不需要文档,因为一周后你自己都忘了它存在——直到某天磁盘满了,你才会想起那个文件名。
但别被这种随意性骗了。真正考验功力的是处理“脏数据”的时候。上个月写了个批量重命名图片的脚本,`for`循环里嵌入`sed`替换,本来以为万无一失。结果跑完发现五十张照片名字全乱了——原来有个文件名里带着换行符,循环直接炸了。那一刻我才明白,shell脚本不是写出来的,是“试”出来的。你得学会用`set -x`盯着每一步,用`echo`在关键位置打标记,甚至故意制造错误来看系统怎么反应。
有人觉得shell只是胶水语言,不算正经编程。我不这么看。它确实没有类型系统,没有面向对象,连数组都别扭得要命。但正因为这种“简陋”,逼着你用最直接的方式解决问题。我写过最长的shell小程序不过一百多行,是个自动部署工具:拉代码、跑测试、重启服务、发通知。每一步都是现成命令的组合,但组合的顺序和条件判断,全是我的逻辑。这跟写Java有什么本质区别?无非工具不同罢了。
对了,还有那些“一次性”的脚本。上周五下午,运营突然要一份三个月内登录过的用户ID列表,数据散在七个不同的日志文件里。我边骂边敲:
cat *.log | awk '{ print $3}' | sort -u > users.txt
十秒钟搞定。这种脚本跑完就删,连文件名都不配拥有。但它们解决的是真问题,比那些精心设计却没人用的“大系统”实在多了。
说到底,shell小程序就是你和Linux之间的私密对话。不需要优雅,不需要健壮,能达成目的就是好代码。就像工具箱里的螺丝刀,你不指望它当锤子用,但拧螺丝的时候,它比什么都好使。下次你看到有人对着终端噼里啪啦打一串“乱码”,别觉得那是命令——那是个程序员在写他的小作品,只不过他的编译器是`bash`,他的调试器是`echo`,而他的IDE,就是那个朴素的黑色窗口。
