linux c实现shell命令解析器
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
linux c实现shell命令解析器.md
11/13/2019
@[toc]
一、实验简介
学习编写此程序可以培养 Linux 系统编程能力,尤其是在多进程方面。可以了解fork、execvp 等重要的 系统调用。另外还能深入到底层理解 Linux Shell 的功能的实现手段。
1.1 知识点
Shell 的基本概念 进程控制相关的系统调用的使用(如 fork,exev) 信号的概念及系统调用 signal的使用 ##1.2 效果截图
/* 执行单条命令行语句 */ void execute(char *command) {
char *arg[MAX_COMM]; char *try; arg[0] = parse(command, 0); int t = 1; arg[t] = NULL;
//获得命令名称的字符串指针,如“ls”
while(1) {
iter = 0; //定义信号处理方式 signal_set();
//用于输出提示符 print_prompt(); //扫描多条命令语句 scan_command(command); // 基于分号解析出单条命令语句,并以字符串的形式存进全局变量 all 中 parse_semicolon(command);
if (out_file != NULL)
{
if (strcmp(out_file, ">") == 0) // 输入输出文件给定
{
out_file = parse(command, 1);
if (out_file == NULL)
{
printf("Syntax error !!\n");
return;
exit(0);
// 循环检测剩下的命令参数,即检测是否:重定向?管道?后台执行?普通命令参数?
while (1)
{
try = parse(command, 1);
if (try == NULL)
break;
else if (strcmp(try, ">") == 0) // 重定向到一个文件的情况
}
else
file_in(arg, try, out_file, 1);
// 参数 1 针对双重定向
<>
}
else if (strcmp(out_file, ">>") == 0)
{
out_file = parse(command, 1);
if (out_file == NULL)
{
printf("Syntax error !!\n");
{
try = parse(command, 1); // 得到输出文件名
file_out(arg, try, 0);
// 参数 0 代表覆盖的方式重定向
return;
}
else if (strcmp(try, ">>") == 0) // 追加重定向到一个文件
{
try = parse(command, 1);
/* 主函数入口 */ /* 主函数入口 */ int main()
2/8
linux c实现shell命令解析器.md
11/13/2019
{ char *command; int iter = 0; command = (char *)malloc(MAX+1); //用于存储命令语句
chdir("/home/"); /* 通常在登陆 shell 的时候通过查找配置文件(/etc/passwd 文件) 中的起始目录,初始化工作目录,这里默认为家目录 */
3/8
linux c实现shell命令解析器.md
11/13/2019
if (strcmp(arg[0], "cd") == 0)
// 处理内嵌命令“cd”的情况
{
try = parse(command, 1);
cd(try);
return ;
}
if (strcmp(arg[0], "exit") == 0) // 为了方便用户推出shell
1/8
linux c实现shell命令解析器.md
##1.3 设计流程
11/13/2019
二、main 函数的设计
首先,以自顶向下的方式探讨一下在 Linux Shell 的周期内主要做了哪些事: 初始化:在这一步,一个典型的 Shell 应该读取配置文件并执行配置功能。这样可以改变 Shell 的行为。 解释:接下来,Shell 将从标准输入 (可以是交互的方式或者一个脚本文件)中读入命令,然后执行它。 终止:在命令被执行之后,Shell 执行关 闭命令,释放内存,最后终止。 详细见代码注释:
// 迭代执行单条命令语句 while(all[iter] != NULL) {
execute(all[iter]); //这是 shell 解释器的核心函数 iter += 1; } } }
注:print_prompt()、scan_command(command) 和 parse_semicolon(command) 三个函数是自定义函 数,功能分别为:用于输出提示符,扫描多条命令语句,基于分号解析出单条命令语句,并以字符串的 形式存进全局变量 all 中。概念简单,其详细代码在项目完整代码中。
#三、程序的核心功能 execute 函数 execute函数完成的主要功能如下:
判断用户执行的是否是 Shell 的内建命令,如果是则执行(这里为了强调概念,没有过多的添加内建命 令) 解析单条命令语句,即将命令名和命令参数解析并保存在字符串数组,以便调用 bf_exec命令。 识别输入输出重定向符号,利用底层系统调用函数 dup2完成上层输入输出重定向 识别后台运行符号,通过设置自定义函数 bf_exec的模式为1实现,这里要说明一点:所谓后台执行,无 非就是让前台 Shell 程序以非阻塞的形式执行,并没有对后台程序做任何操作 这部分的完整代码如下:
file_out(arg, try, 1);
// 参数 1 代表追加的方式重定向
return;
}ቤተ መጻሕፍቲ ባይዱ
else if (strcmp(try, "<") == 0) // 标准输入重定向
{
try = parse(command, 1);
// 输入重定向的输入文件
char *out_file = parse(command, 1); // 输出重定向的输出文件
11/13/2019
@[toc]
一、实验简介
学习编写此程序可以培养 Linux 系统编程能力,尤其是在多进程方面。可以了解fork、execvp 等重要的 系统调用。另外还能深入到底层理解 Linux Shell 的功能的实现手段。
1.1 知识点
Shell 的基本概念 进程控制相关的系统调用的使用(如 fork,exev) 信号的概念及系统调用 signal的使用 ##1.2 效果截图
/* 执行单条命令行语句 */ void execute(char *command) {
char *arg[MAX_COMM]; char *try; arg[0] = parse(command, 0); int t = 1; arg[t] = NULL;
//获得命令名称的字符串指针,如“ls”
while(1) {
iter = 0; //定义信号处理方式 signal_set();
//用于输出提示符 print_prompt(); //扫描多条命令语句 scan_command(command); // 基于分号解析出单条命令语句,并以字符串的形式存进全局变量 all 中 parse_semicolon(command);
if (out_file != NULL)
{
if (strcmp(out_file, ">") == 0) // 输入输出文件给定
{
out_file = parse(command, 1);
if (out_file == NULL)
{
printf("Syntax error !!\n");
return;
exit(0);
// 循环检测剩下的命令参数,即检测是否:重定向?管道?后台执行?普通命令参数?
while (1)
{
try = parse(command, 1);
if (try == NULL)
break;
else if (strcmp(try, ">") == 0) // 重定向到一个文件的情况
}
else
file_in(arg, try, out_file, 1);
// 参数 1 针对双重定向
<>
}
else if (strcmp(out_file, ">>") == 0)
{
out_file = parse(command, 1);
if (out_file == NULL)
{
printf("Syntax error !!\n");
{
try = parse(command, 1); // 得到输出文件名
file_out(arg, try, 0);
// 参数 0 代表覆盖的方式重定向
return;
}
else if (strcmp(try, ">>") == 0) // 追加重定向到一个文件
{
try = parse(command, 1);
/* 主函数入口 */ /* 主函数入口 */ int main()
2/8
linux c实现shell命令解析器.md
11/13/2019
{ char *command; int iter = 0; command = (char *)malloc(MAX+1); //用于存储命令语句
chdir("/home/"); /* 通常在登陆 shell 的时候通过查找配置文件(/etc/passwd 文件) 中的起始目录,初始化工作目录,这里默认为家目录 */
3/8
linux c实现shell命令解析器.md
11/13/2019
if (strcmp(arg[0], "cd") == 0)
// 处理内嵌命令“cd”的情况
{
try = parse(command, 1);
cd(try);
return ;
}
if (strcmp(arg[0], "exit") == 0) // 为了方便用户推出shell
1/8
linux c实现shell命令解析器.md
##1.3 设计流程
11/13/2019
二、main 函数的设计
首先,以自顶向下的方式探讨一下在 Linux Shell 的周期内主要做了哪些事: 初始化:在这一步,一个典型的 Shell 应该读取配置文件并执行配置功能。这样可以改变 Shell 的行为。 解释:接下来,Shell 将从标准输入 (可以是交互的方式或者一个脚本文件)中读入命令,然后执行它。 终止:在命令被执行之后,Shell 执行关 闭命令,释放内存,最后终止。 详细见代码注释:
// 迭代执行单条命令语句 while(all[iter] != NULL) {
execute(all[iter]); //这是 shell 解释器的核心函数 iter += 1; } } }
注:print_prompt()、scan_command(command) 和 parse_semicolon(command) 三个函数是自定义函 数,功能分别为:用于输出提示符,扫描多条命令语句,基于分号解析出单条命令语句,并以字符串的 形式存进全局变量 all 中。概念简单,其详细代码在项目完整代码中。
#三、程序的核心功能 execute 函数 execute函数完成的主要功能如下:
判断用户执行的是否是 Shell 的内建命令,如果是则执行(这里为了强调概念,没有过多的添加内建命 令) 解析单条命令语句,即将命令名和命令参数解析并保存在字符串数组,以便调用 bf_exec命令。 识别输入输出重定向符号,利用底层系统调用函数 dup2完成上层输入输出重定向 识别后台运行符号,通过设置自定义函数 bf_exec的模式为1实现,这里要说明一点:所谓后台执行,无 非就是让前台 Shell 程序以非阻塞的形式执行,并没有对后台程序做任何操作 这部分的完整代码如下:
file_out(arg, try, 1);
// 参数 1 代表追加的方式重定向
return;
}ቤተ መጻሕፍቲ ባይዱ
else if (strcmp(try, "<") == 0) // 标准输入重定向
{
try = parse(command, 1);
// 输入重定向的输入文件
char *out_file = parse(command, 1); // 输出重定向的输出文件