Shell实现(三)读取命令的实现
2015-10-24 22:37
471 查看
基本思路
读取命令我采取的读取整个字符串后再进行分段和分析:首先是parse_token将字符串通过分号为分隔,得到每组命令,每组命令当中只包含管道,输入输出重定向和单条命令及其参数。
然后是parse_group将每段得到的字符串通过管道为分隔,得到只包含参数,输入输出重定向和单条命令的更加简单的命令串
最后是parse_command分析单条指令,得到输入输出重定向的文件流和命令的属性还有命令的参数。
从内存中取出占位放入命令,然后将命令分组(组内连续)
具体实现:
首先是parse_token//遍历字符串以";"为分隔得到字符串组,用0取代;代表字符串结束,实现字符串的划分 void parse_token ( char* buf ) { int n = strlen ( buf ),i,j=0; n--; buf = 0; for ( i = 0 ; i < n ; i++ ) if ( buf[i] == ';'|| i == n-1 ) { if ( buf[i] == ';' ) buf[i] = 0; parse_group ( buf+j ); j = i+1; } }
然后是parse_group,与parse_token思路相似
//以“|”为分隔得到字符串组,用0取代|的位置代表字符串结束,实现字符串的划分 //mode代表得到的单条指令在组中的位置,只有两端的不通过管道的传递信息 //1代表中间位置 void parse_group ( char* buf ) { int n = strlen ( buf ),i,j=0; int x = cnt_cmd; for ( i = 0 ; i < n ; i++ ) if ( buf[i] == '|' || i == n-1 ) { int mode = 0; if ( buf[i] == '|' ) { buf[i] = 0; mode = 1; } parse_command ( buf+j , mode ); j = i+1; } group[cnt_group].first = x;//对指令进行分组 group[cnt_group].last = cnt_cmd; cnt_group++; }
最后是parse_command
//parse_command分析单条指令 void parse_command ( char* buf , int mode ) { int n = strlen ( buf ),i=0,j=0; while ( buf[i] ==' '|| buf[i] == '\t' ) i++,j++;//去掉没有用的空格 int id = init_cmd ();//从内存池中取出一个命令的槽 if ( mode == 1 ) cmd[id].type |= PIPE;//如果命令位于中间位置,那么设置为属性包含PIPE属性 char* segment[MAX_ARGS];//存储划分段的位置的指针 int x=0; for ( ; i < n ; i++ ) if ( buf[i] == ' ' || i == n-1 ) { if ( buf[i] == ' ' ) buf[i] = 0; segment[x++] = buf+j; j = i+1; while ( buf[j] == ' ' || buf[j] == '\t' ) j++,i++; } //分析指令,查找文件的重定向和向参数列表中添加参数 int temp = 0; cmd[id].cmd = segment[0]; cmd[id].param = malloc(sizeof (char*)*(MAX_ARGS+2) ); if ( x > 0 ) cmd[id].param[temp++] = segment[0]; for ( i = 1; i < x ; i++ ) { int flag = 1; if ( strlen(segment[i]) == 1 ) { if ( segment[i][0] == '<' ) { flag = 0; cmd[id].input = segment[i+1]; i++; } else if ( segment[i][0] == '>' ) { flag = 0; cmd[id].output = segment[i+1]; i++; } } if ( strlen ( segment[i] ) == 2 ) { if ( strcmp ( segment[i] , "<<" ) == 0 ) { flag = 0; cmd[id].input = segment[i+1]; i++; } else if ( strcmp ( segment[i] , ">>" ) == 0 ) { flag = 0; cmd[id].output = segment[i+1]; i++; } } if ( flag ) { cmd[id].param[temp++] = segment[i]; } } }
需要用到的函数库中的函数
string.h里的一些简单的字符串操作函数char* flag = fgets ( buf , BUFSIZE , stdin);用于读取一行数据的函数,第一个是缓存区间的首地址,第二个为缓存区间的规模,第三个为输入流
malloc向堆申请内存
相关文章推荐
- android wifi 无线调试
- 运维入门
- 动态清空 nohup 输出文件
- install scrapy with pip and easy_install
- Linux Shell常用技巧
- Shell 脚本编程陷阱
- shell字符串操作详解
- Shell中删除某些文件外所有文件的3个方法
- Ruby中执行Linux shell命令的六种方法详解
- VB使用shell函数打开外部exe程序的实现方法
- Shell编程的一些知识集合
- Shell中的for和while循环详细总结
- 什么是Shell?Shell脚本基础知识详细介绍
- Shell脚本中引用、调用另一个脚本文件的2种方法
- Shell脚本解压rpm软件包
- Linux Shell 数组建立及使用技巧
- Shell脚本实现复制文件到多台服务器的代码分享
- Shell脚本实现批量替换文件内容
- Shell脚本实现的一个简易Web服务器例子分享
- linux Shell学习笔记第五天