shell.c/shell.h
shell.c是main()函数的所在,它定义了shell启动和运行过程中的一些状态量,依据不同的启动参数、环境变量等来初始化shell的工作状态(包括受限模式等),之后进入eval.c中的交互循环函数reader_loop()解析命令直到退出。
初始化函数shell_initialize()调用了variables.c中的initialize_shell_variables()、set.c中的initialize_shell_options()等一系列子模块初始化函数。如果要新增功能模块,可以将它们的初始化调用放在这里。
run_startup_files()函数执行~/.profile、~/.bash_profile、~/.bash_login等配置文件,同时判断了bash是否是由sshd或rshd启动的。对于login shell,不执行~/.bashrc;对于non-login交互式shell,或通过sshd、rshd启动的shell,执行~/.bashrc。
run_one_command()函数处理了-c参数运行一条命令的模式。
open_shell_script()函数处理运行脚本文件的模式。
退出函数exit_shell()处理了挂起作业、保存历史等善后工作。
eval.c
读取并解释执行shell命令。主循环为reader_loop()函数,它调用read_command(),read_command()调用parse_command(),parse_command()调用语法分析器y.tab.c中的yyparse()。得到命令后,reader_loop()调用execute_cmd.c中的execute_command()执行命令。
注:token查找优先顺序:别名>关键字>函数>内部命令>脚本或可执行程序。
execute_cmd.c/execute_cmd.h
执行命令(COMMAND结构)。外部调用接口是execute_command(),内部通过execute_command_internal()执行命令。execute_command_internal()包含可选的管道重定向以及后台运行的参数。
针对不同类型的命令(控制结构、函数、算术等),execute_command_internal()调用不同的函数来完成相应功能。其中execute_builtin()执行内部命令;execute_disk_command()执行外部文件。execute_disk_command()通过调用jobs.c或nojobs.c中的make_child()来fork新进程执行。
本文件中维护了一个文件描述符的位图。
make_cmd.c/make_cmd.h
构造各类命令、重定向等语法结构实例所需的函数。由语法分析器、redir.c等调用。
其中make_redirection()填写命令结构的重定向参数。
copy_command.c
用来递归复制各种COMMAND结构的一系列函数。
作者注释称:This is needed primarily for making function definitions, but I'm not sure that anyone else will need it.
dispose_command.c/dispose_command.h
清理COMMAND结构占用的资源,dispose_redirects()清理重定向语句。
print_cmd.c
将命令结构转化为可打印的字符串。在execute_cmd.c的execute_command_internal()中有调用。
redir.c/redir.h
实现输入输出重定向。在执行之前,命令结构的redirects参数已由make_cmd.c填好,外部主要由execute_cmd.c调用以执行重定向操作。
外部调用接口是do_redirections(),它解析命令结构的重定向参数,内部交由do_redirection_internal()执行。接着依据不同的重定向类型,redir_open()分别使用常规的open()、redir_special_open()、noclobber_open()等函数打开重定向的文件描述符。如果要添加新的重定向方式(如重定向到FTP),可考虑在这里添加代码。
重定向原理参见参考文献《Unix/Linux编程实践教程》10.3节。
paser.y
yacc语法定义文件。
y.tab.c/y.tab.h
yacc生成的语法分析器。
解析token,调用make_cmd.c中的函数,生成命令结构,便于execute_cmd.c中的函数执行。
其中包括调用make_redirection()填写命令结构的重定向参数。
alias.c/alias.h
别名操作相关函数,包括增、删、查、改等。内部命令alias的实现是调用本文件中的函数。
array.c/array.h/arrayfunc.c/arrayfunc.c
字符串数组定义及相关函数,实现了数组的一些高级操作。bash程序中一些字符串数组使用了这里定义的ARRAY结构。
bashansi.h
针对不同的编译器处理一些系统头文件的包含关系。
bashhist.c/bashhist.h
命令历史记录功能相关的函数,包括历史记录的启、停、增、查等。
bashintl.h
引入locate.h、gettext.h等国际化支持。
bashjmp.h
对setjmp.h的一层封装,定义了longjmp()的几种状态参数。
bashline.c/bashline.h
与readline库的接口,解决命令自动补全、类emacs与vi行编辑功能等。
bashtypes.h
定义了word类型。
bracecomp.c/braces.c
使用大括号通配文件名功能的函数。
builtins.h
定义内部命令的基本结构struct builtin。
command.h
各类命令(控制结构、函数、算术、重定向等)的结构定义。
config.h/config-top.h/config-bot.h
config.h由configure生成,决定有哪些特性要被编译进bash。如果要新增功能,可以加一个“开关”宏定义。
conftypes.h
定义主机体系结构和操作系统类型的名称。
error.c/error.h
错误处理与报告函数。
expr.c
处理算术表达式。外部调用接口是evalexp()。
externs.h
声明一些源文件中的函数,它们在自己的头文件中没有声明。
findcmd.c/findcmd.h
通过名字查找命令。主要是从PATH变量位置查找外部可执行程序。
flags.c/flags.h
存储和处理各个运行状态标志,如Standard Sh Flags与Non-Standard Flags。
general.c/general.h
很多文件可能公用的一些基础的、不便分类的函数。
hashcmd.c/hashcmd.h
管理哈希表,主要用于将命令名字映射到完整路径。
hashlib.c/hashlib.h
哈希表的数据结构。
input.c/input.h
处理输入流缓冲。
jobs.c/jobs.h
作业控制。主要入口是make_child(),用来创建进程并执行。
jobs、fg、bg、kill等命令的内部实现都在这里。
作业管理详细流程暂未分析。
nojobs.c
在未实现作业控制的操作系统中代替jobs.c编译。
list.c
链表数据结构。
locale.c
与国际化相关的函数,包括对“LC_”系列环境变量的操作。
lsignames.h/signames.h
定义了各种信号的名称字符串。signames.h是由编译时辅助工具mksignames生成的,mksignames的源代码在support子目录。
mailcheck.c/mailcheck.h
检查账户邮箱的函数。
mksyntax.c
用来生成编译时辅助工具mksyntax。mksyntax与用来构建词法分析文件syntax.c。
syntax.c/syntax.h
syntax.c是由mksyntax生成的词法分析文件,syntax.h定义了词法分析工作中需要的宏和标志位等。
parser.h
parse.y和bashhist.c所需的定界符栈结构(struct dstack)的定义。
patchlevel.h
记录bash的修正版本号。
pathexp.c/pathexp.h
与通配(globbing)库的接口。
pathnames.h
记录一些操作系统配置文件的路径。
pcomplete.c/pcomplete.h/pcomplib.c
可编程的命令补全功能。
quit.h
定义通用的异常退出宏,是对SIGINT信号的响应。
sig.c/sig.h/siglist.c/siglist.h
信号处理相关函数。
stringlib.c
字符串处理相关函数。包括从字符串-整数键值对结构(ALIST)中查找数据项等函数。
subst.c/subst.h
负责参数、命令、算术、路径扩展、引号等的代入、展开工作。
test.c/test.h
GNU test program,各类条件比较条令,在shell脚本中常用。
trap.c
操作trap命令所需的一些对象的函数。
unwind_prot.c/unwind_prot.h
通用的函数执行保护和退出处理机制。
variables.c/variables.h
处理shell变量。用不同的哈希表分别存储不同生命周期的shell变量与函数。
变量列表是由当前环境来初始化的。bash启动时环境由main()的char **env参数传入。
对于函数,使用栈来保存和切换局部变量的上下文。
version.c/version.h
显示bash版本号。
xmalloc.c/xmalloc.h
安全版本的malloc封装。