编写简单的shell命令解析器

                                                     编写简单的shell命令解析器

环境:

RedHat 9.0    内核 2.4.20

vi 文书编辑器  6.1.320

gcc  3.2.2-5

 

实现步骤:

 

0步:写一个最简单的shell命令解释器,本程序取自APUE1-5,命令不能带参数。

 

需要完成的内容如下:

  1. 命令解释器首先是一个死循环。

  2. 打印一个命令提示符。

  3. 取得命令行输入放在数组里面,不要求命令带参数。可以getc()fgets()scanf()等。

  4. 如果用fgets()的话,取得的字符串包括最后输入的换行符,故要去掉命令字符串末尾的“/n”,变成“/0

  5. 创建一个子进程,调用exec执行命令。

  6. 父进程调用waitpid()等待子进程的退出,然后进入下一次循环。

 

1步:写一个shell命令解释器,使能处理带参数的命令。

 

需要完成的内容如下:

  1. 命令解释器首先是一个死循环。

  2. 打印一个命令提示符,包含当前路径信息。取得命令行输入,本程序是把命令行输入保存在一个字符指针指向的地址中。

  3. 分析命令行,把以空格分开的命令和参数

分别取出来放在字符指针数组arg[]中。这里取得的命令行字符串保存在input指向的地址。为了把这一行字符串中的命令和参数分开,需要一个临时数组tmp(本程序是重用前面使用的buf数组),把input指向命令行中的命令和参数分别保存在arg[0]arg[1]等等。

    4 .  创建一个子进程,调用exec执行命令。

    5.   父进程(即shell命令解释器)根据命令是在前台还是后台运行,决定是否调用waitpid()。然后进入下一次循环。

 

2步:加入内部命令cdexit

 

需要完成的内容如下:

  

     1.以第1步为基础,在分析完命令行输入后,看输入的命令arg[0]是不是“exit或者“cd,如果是的话,在执行创建子进程去执行这个命令之前就做为内部命令执行。

     2.exit命令的实现只要打印一句话“Bye bye!,然后释放前面分配的内存空间,然后退出即可。

       3.cd命令的实现用到函数chdir(arg[1]),它用来改变当前工作目录。

 

3步:程序的实现分别放在几个文件中,引入头文件的概念。引入重定向和管道函数,但不用具体实现这两个函数。

 

需要完成的内容如下:

     1.引入头文件,把公共的变量和函数放在头文件中,注意防止头文件被重复包含。

     2. 处理用户输入的命令行中包含重定向符号和管道符号的情况。使用函数redirect()my_pipe()处理重定向和管道,这两个函数的实现放在一个单独的文件中,不用具体实现这两个函数。

 

4步:引入环境变量配置文件mysh_profile,读取环境变量,判断文件是否存在,若存在,执行命令,否则打印“command not found

 

需要完成的内容如下:

    1.创建一个环境变量配置文件,里面的内容是一行PATH环境变量如下:PATH=/bin:/sbin:/usr/bin:/usr/sbin

      2.创建函数init_environ(),读取环境变量到数组。

    3.创建函数is_founded(),查找文件,看文件是否存在。

 

5步:实现重定向功能。

 

需要完成的内容如下:

    在redirect.c文件中实现redirect()函数。

 

6步:实现管道功能

 

需要完成的内容如下:

    在pipe.c文件中实现my_pipe()函数。

 

7步:实现历史记录命令history

 

需要完成的内容如下:

     1. 在头文件mysh.h中增加表示历史记录的循环数组的数据类型,并定义相应变量。

     2. 在history.c中实现函数add_history()history_cmd()

     3.在main.c中,分别在管道、重定向、内部命令、普通命令执行前,把命令行内容加入到命令历史记录循环数组中。

 

8步:实现后台作业队列,加入内部命令jobsbgfg命令。

 

 

 

 

 

测试完成的功能:

第0步骤:
1. 要求每个命令完成后,重新打印出提示符
2. 测试:ls cat 等命令

第1步骤:参数
1. 提示符中出现当前路径信息。
2. 测试命令“ls”,“ls<空格>”,“<空格>ls”,“<空格>ls<空格>”
   “ls -a -l”  ,“<空格>ls <多个空格> -a <多个空格>-l”

第2步骤:cd exit
1. 测试"cd ..", "cd /home" , "cd -" , "cd~" 等命令

第4步骤:环境变量
1. 把/bin/ls文件拷贝到/home目录,
    并将/bin/ls重命名为/bin/ls-bk,测试ls命令
2.在环境变量文件mysh_profile中添加"/home"目录,测试ls命令

第5步骤:重定向
1. 测试 "ls>test" , "ls(空格)>(空格)test" , "ls(空格)>test"命令
2. 测试 "ls>>test" , "ls(空格)>>(空格)test" , "ls(空格)>>test"命令
3. 测试"cat<test" , "cat(空格)<(空格)test",  "cat(空格)<test"命令
4. 测试"cat>test<test1", "cat>test1<test"命令。test由 "ls -al >> test"生成

第6步骤:管道
1. 测试"ls(空格)|(空格)more"命令

第7步骤:历史记录
1. 测试用上下键从历史记录中提取命令

第8步骤:作业管理
1. 测试jobs, bg , fg, "Ctrl+c","Ctrl+z" 命令

 

 

总结:这个项目主要涉及到的知识:进程控制、进程通信。当然,c语言的基础是最重要的。

        项目的基本功能已实现,但存在一些待解决问题:1.历史命令调出,对之进行增减后还不能执行相应的命令;2.jobs链表的建立没加上判断条件,导致执行后台命令时链表保存重复的内容。

 

源代码位置:

http://download.csdn.net/source/1237870

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值