自主实现一个shell

本文介绍了如何实现一个具备基本命令处理能力的shell,包括命令解析、输入输出重定向、管道、后台作业等功能。通过解析命令行,使用fork和execvp执行外部命令,使用dup处理重定向,pipe实现管道,并讨论了cd、jobs、kill等内部命令的实现。尽管存在一些限制和未实现的功能,但该shell提供了基础的命令行交互体验。
摘要由CSDN通过智能技术生成

我实现的shell具有以下功能:

1. 支持ls,touch,wc 等外部命令

2. 支持输入输出重定向符

3. 支持管道命令

4 .支持后台作业

5. 支持cd,jobs,kill,exit等内部命令(自己还写了一个about 命令 ^ _ ^)

6. 支持对ctrl+c 和ctrl +z 信号的处理


接下来我们按照编写的步骤一一来分析:

(一)命令的解析

输入命令的解析在本程序中占到了很大的比重,虽然像这种解析普通命令的程序(正则表达式太难了。。)的解释器难度不大,但是健壮性和全面性还是需要周全考虑的。
这里采用了分段解析,先除去起始空格,制表符等,并以此和一些‘|’,‘<’为分割界限来解析命令至COMMAND结构体。直接看代码吧,注释很详细!

  1. /* 
  2.  * 解析命令 
  3.  * 成功返回解析到的命令个数,失败返回-1 
  4.  */  
  5. int parse_command(void)  
  6. {  
  7.     /* cat < test.txt | grep -n public > test2.txt & */  
  8.     if (check("\n"))  
  9.         return 0;  
  10.   
  11.     /* 判断是否内部命令并执行它 */  
  12.     if (builtin())  
  13.         return 0;  
  14.   
  15.   
  16.     /* 1、解析第一条简单命令 */  
  17.          
  18.     get_command(0);  
  19.     /* 2、判定是否有输入重定向符 */  
  20.     if (check("<"))  
  21.         getname(infile);  
  22.     /* 3、判定是否有管道 */  
  23.     int i;  
  24.     for (i=1; i<PIPELINE; ++i)  
  25.     {  
  26.         if (check("|"))  
  27.             get_command(i);  
  28.         else  
  29.             break;  
  30.     }  
  31.     /* 4、判定是否有输出重定向符 */  
  32.     if (check(">"))  
  33.     {  
  34.         if (check(">"))  
  35.             append = 1;  
  36.         getname(outfile);  
  37.     }  
  38.     /* 5、判定是否后台作业 */  
  39.     if (check("&"))  
  40.         backgnd = 1;  
  41.     /* 6、判定命令结束‘\n’*/  
  42.     if (check("\n"))  
  43.     {  
  44.         cmd_count = i;  
  45.         return cmd_count;  
  46.     }  
  47.     else  
  48.     {  
  49.         fprintf(stderr, "Command line syntax error\n");  
  50.         return -1;  
  51.     }  
  52. }  
  53.   
  54. /* 
  55.  * 解析简单命令至cmd[i] 
  56.  * 提取cmdline中的命令参数到avline数组中, 
  57.  * 并且将COMMAND结构中的args[]中的每个指针指向这些字符串 
  58.  */  
  59. void get_command(int i)  
  60. {  
  61.     /*   cat < test.txt | grep -n public > test2.txt & */  
  62.   
  63.     int j = 0;  
  64.     int inword;  
  65.     while (*lineptr != '\0')  
  66.     {  
  67.         /* 去除空格 */  
  68.         while (*lineptr == ' ' || *lineptr == '\t')  
  69.             lineptr++;  
  70.   
  71.         /* 将第i条命令第j个参数指向avptr */  
  72.         cmd[i].args[j] = avptr;  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值