
谢邀。先安利一个表达力强、UI 友好的新 POSIX shell:
。elvish 代码简单,适合拿来研究学习。
问题的答案取决于题主想要实现传统的 POSIX shell 还是另辟蹊径做一个更像样的非 POSIX shell 。实现传统的 POSIX shell 不需要多少“正统”编译原理的知识。因为 POSIX shell 的解释过程是若干次文本替换(所谓“expansion”)的过程,而不是通常的先解析成语法树再执行。好处是没有任何理论深度,按照 POSIX 标准来就行了。坏处是用正常的技术解析 POSIX shell 反而很麻烦,即使能够解析,要完全模拟 expansion 的语义也不简单。个人意见:POSIX shell 历史包袱太多,而且早已被 zsh 做到了极致,因此既缺少练习的价值也缺少实用的价值,在 2015 年去实现一个新的 POSIX shell 是事倍功半的事。
如果打算实现一个新的非 POSIX shell,那么不得不会的编译原理知识就是基本的解析(parsing)技术。不过有点头疼的是,处理不完整、病态输入的技术在一般的编译原理教科书上是不深入探讨的,理论方面也比较欠缺。但是这类技术对 tab 补全十分重要,需要自己摸索或者参照现有的实现。
如果追求性能的话,还要学习 VM 和 JIT。但如果只是应付交互使用,直接执行解析出来的 AST、甚至边解析边执行也没问题,反而可能更方便。
shell 和普通的编程语言最大的区别在于,它还要求很多系统编程的知识,主要是进程和 I/O(下面包括终端 I/O)这两方面。对照 Advanced Programming in Unix Environment 第二版的目录,第三章文件 I/O、第八章进程控制、第九章进程关系、第十章信号、第十四章高级 I/O、第十八章终端 I/O 里的知识几乎全都能用上。Unix 系统编程坑不少,要想做一个好的 shell,得对系统接口相当了解才行。
最后再安利几句。如果楼主有志于改进 Unix shell 现状,不妨看看 elvish 源码并参与它的设计和实现。如果答主更喜欢语义上更简单(同时表达力也更弱)的 shell 的话,fish (
) 作为在现代 Unix 生态下流行开的第一个非 POSIX shell,给它作贡献也是个选择。不过如果你读过 fish 和 elvish 的代码的话,肯定还是会更喜欢 elvish 的。:-P
