操作系统 实现简单shell程序 sh3.c
在sh2基础上加管道功能
只实现了单个管道,改善了在sh2实现的字符串切割函数
功能和要求
实现shell程序
使用fork/exec/wait系统调用实现mysys
实现文件重定向
实现管道,只要求连接两个命令,不要求连接多个命令,不要求同时处理管道和重定向
实现思路
1.输入一行字符串
2.调用parse_command把字符串根据管道符号进行简单分割
简单分割后的token再调用parse_command_s进行完整分割
分割后的字符串保存到struct command【】中
3.根据command_count的值判断是带有管道的命令 还是非管道命令
- 如果是管道命令:执行mysys_pipe()
- 如果不是管道命令:先判断是否存在重定向
- 存在重定向:先执行redirect(),再执行mysys_simple()
- 不存在重定向:直接执行mysys_simple()
4.把结构体内容清空,进行下一次循环
函数和变量说明
#define MAX_LEN 100
#define MAX_ARGC 16
int command_count = 0;
struct command{
int argc;
char *argv[MAX_ARGC];
char input[MAX_LEN];
char output[MAX_LEN];
}Cmd[4];
void mysys_simple(struct command *c) //不包含管道和重定向的shell命令
void mysys_pipe() //实现管道命令
void redirect(struct command *c) //重定向
void dump_command(void) //打印结构体信息
void parse_command(char *line) // 根据管道符对line进行切割
void parse_command_s(char *line,int c_count)
//把不包含管道符的line字符串切割存到command【】中
strtok()
char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针
parse_command(char *line)
-
对字符串根据管道符号“|”进行简单分割,确保每一个字符串中不存在“|”
-
根据“|”确定command_count的值,和command结构体的数量
-
对简单分割后的每一个字符串调用一次parse_command_s进行完整的切割,把
切割的结果存放到一个struct command结构体的input ,output, argv[]中
void parse_command(char *line){
char *token_s;
char *buf1 = NULL;
token_s = strtok_r(line,"|",&buf1);
while( token_s ){
parse_command_s(token_s,command_count);
command_count++;
token_s=strtok_r(NULL,"|",&buf1);
}
}
parse_command_s(char *line,int c_count)
字符串中不存在管道符后,调用parse_command_s,切割采用strtok_r函数
- 把line根据空格进行切割,切割得到的结果存放到argc和argv[ ],input output中
void parse_command_s(char *line,int c_count){
char buffer[MAX_LEN]={
'\0'};
memset(buffer,0,sizeof(buffer));
strcpy(buffer,line);
int count=0;
char *token