|

楼主 |
发表于 2007-6-12 00:35:56
|
显示全部楼层
Post by Souryu_Asuka
实现一个shell……基本是Linux编程的入门功夫吧。
实现一个功能高度简化的SHELL,确实很简单,属于Linux编程的入门功夫,使用strtok、fork、execlp三个函数不超过100行源代码就可以完成了。实际中的Shell是一个比较复杂的程序,即使是BASH的早期版本,它的源代码规模也要在30,000行左右,更不用说现在的Bash3了;BusyBox中自带的SHELL是来自于Berkeley的ASH,源代码规模在15,000行左右。
考虑实现一个实际Shell中的如下功能:
- 提供选择、循环等控制语句,支持函数。
这需要进行语法分析。在bash中使用的是yacc、busybox中的shell使用的是递归下降进行语法分析。语法分析得到语法树后,可以使用两种方式处理语义:
- 把语法树转换成四元式序列,对break和continue指令的处理就比较简单,但是这样做比较麻烦。
- 直接解释语法树,但是解释break和continue指令时会遇到困难。
- 管道命令的组成可以是简单命令也可以是复杂命令
最初的C shell的一个缺点就是管道只能由简单命令组成,这样解释起来就比较简单。而Bourne Shell中,是允许复杂命令进出管道的,实现起来就复杂多了。 - 不仅能够对基本的命令重定向,而且可以对复杂命令重定向
和上面一样,只对简单命令重定向很简单,如果实现对复杂命令重定向就比较复杂,举例:
- while [ 1 -lt 2 ]; do
- whle [ 2 -lt 3 ]; do
- echo hello
- done > inner.txt
- echo world
- done >outter.txt
复制代码
- 支持多种类型的参数替换
实现这样的功能要比我们想像中的复杂,因为这些替换是可以互相嵌套的,暂且不说参数替换,单单是把参数分割开来就很麻烦了,举例:
- echo `echo $(echo ${VAR:-\`echo *\`})`
复制代码
对这个例子进行词法分析时,应该被分割成两个单词。
另外有些看上去不起眼的功能实现起来很麻烦,比如说文件名匹配:
- $ mkdir {a,b,c}/{a,b,c}/{a,b,c}
- $ ls a/*/c
复制代码
mkdir创建了27个目录,b/*/b匹配的是a/a/c、a/b/c、a/c/c三个目录。在UNIX中,被匹配的文件可以不在同一个目录下;而在DOS中,只能匹配同一个目录下子文件,DOS提供的功能之所以弱,是因为匹配同一目录下的子文件简单多了。
这个帖子可能发错版面了,可惜东方教主不在啊。 |
|