📄 shell.cpp
字号:
real_order[i]='\0'; i++; if(flag_out==1&&input[i]=='>') { flag_out=2; i++; } else if (flag_in==1&&input[i]=='<') { flag_in=2; i++; } //读出前面的空格 while ((input[i]==' '||input[i]==' ')&&i<len) i++; j=0; out_filename[0]='\0'; in_filename[0]='\0'; //读取定向输入或输出的文件 if(flag_out>0) { while (i<=len) { if(input[i]=='<') { out_filename[j]='\0'; break; } out_filename[j]=input[i]; i++; j++; } } if(flag_in>0) while (i<=len) { if (input[i]=='>') { in_filename[j]='\0'; break; } in_filename[j]=input[i]; i++; j++; } //既存在输出重定向也存在输入重定向 if (i<len) { j=0; if (flag_out>0&&input[i]=='<') { i++; flag_in=1; if(input[i]=='>') { flag_in=2; i++; } //读出前面的空格 while ((input[i]==' '||input[i]==' ')&&i<len) i++; while (i<=len) { in_filename[j]=input[i]; i++; j++; } } else if (flag_in>0&&input[i]=='>') { i++; flag_out=1; if(input[i]=='>') { flag_out=2; i++; } //读出前面的空格 while ((input[i]==' '||input[i]==' ')&&i<len) i++; while (i<=len) { out_filename[j]=input[i]; i++; j++; } } else { fprintf(stderr,"ERROR!can't find the file!\n"); return -1; } } //for debug /*printf("real_order: %s\n",real_order); printf("out_filename: %s\n",out_filename); printf("in_filename: %s\n",in_filename);*/ k=number(real_order); analized_order=analize(real_order);//命令已经保存在*analized_order[]中 if(strcmp(analized_order[0], "leave") == 0) //退出命令 { printf("bye-bye\n"); // 释放申请的空间 for(i=0;i<k;i++) free(analized_order[i]); free(analized_order); free(real_order); exit(1); return 1; } /*如果输入的是cd命令*/ if (strcmp(analized_order[0],"cd")==0) { do_cd(analized_order); // 释放申请的空间 for(i=0;i<k;i++) free(analized_order[i]); free(analized_order); free(real_order); return 1; } order_path=is_file_exist(analized_order[0]); if(order_path==NULL) //can't find the order { fprintf(stderr,"This is command is not founded ?!\n"); // 释放申请的空间 for(i=0;i<k;i++) free(analized_order[i]); free(analized_order); free(real_order); return -1; } //创建子进程用于执行命令 if((pid = fork()) == 0) { /* 存在输出输入重定向*/ if(flag_out==1) fd_out = open(out_filename,O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); if(flag_out==2) fd_out = open(out_filename, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR ); if(flag_in==1) fd_in = open(in_filename, O_RDONLY, S_IRUSR|S_IWUSR ); if(flag_in==2) fd_in = open(in_filename, O_RDONLY, S_IRUSR|S_IWUSR ); if(fd_out==-1) { printf("Open out %s error \n", out_filename); return -1; } if(fd_in==-1) { fprintf(stderr,"Open in %s error \n", in_filename); return -1; } //使用dup2函数将标准输出重定向到fd_out上 if(flag_out>0) if(dup2(fd_out, STDOUT_FILENO) == -1) { fprintf(stderr,"Redirect Standard Out Error !\n"); exit(1); } //使用dup2函数将标准输入重定向到fd_in上 if(flag_in>0) if (dup2(fd_in,STDIN_FILENO)==-1) { fprintf(stderr,"Redirect Standard Out Error !\n"); exit(1); } execv(order_path,analized_order); exit(1); //子进程推出 } else //父进程 if(back==0) // 并非后台执行指令 pid=waitpid(pid, &status, 0); // 释放申请的空间 free(out_filename); free(in_filename); free(order_path); for(i=0;i<k;i++) free(analized_order[i]); free(analized_order); return 1;}int is_back(char *order) //分析是否为后台进程,并且将字符&去掉{ int len=strlen(order); if(order[len]=='&') { order[len]='\0'; return 1; } else return 0;}char *is_file_exist(const char *order) //判断命令是否存在{ char * path, * p; char *buffer; int i,max_length; i = 0; /* 使用getenv函数来获取系统环境变量,用参数PATH表示获取路径*/ path=getenv("PATH"); p=path; max_length=strlen(path)+strlen(order)+2; if((buffer=(char *)malloc(max_length*(sizeof(char))))==0) { fprintf(stderr,"error! can't malloc enough space for buffer\n"); return NULL; } while(*p != '\0') { /* 路径列表使用":"来分隔路径*/ if(*p != ':') buffer[i++] = *p; else { buffer[i++] = '/'; buffer[i] = '\0'; /* 将指令和路径合成,形成pathname,并使用access函数来判断该文件是否存在*/ strcat(buffer,order); if(access(buffer,F_OK) == 0) /* 文件被找到*/ return buffer; else /* 继续寻找其他路径*/ i=0; } p++; } /* 搜索完所有路径,依然没有找到则返回 NULL*/ return NULL;}int number(const char *input) //分析命令和参数数量,来划分相应字符串{ int i=0,k=0; int input_len=strlen(input); k=0; //k记录命令和参数数量 int flag=0; for (i=0;i<input_len;i++) { if(input[i]==' '||input[i]=='<'||input[i]=='>'||input[i]==' ') { flag=0; continue; } else { if(flag==0) { flag=1; k++; } } } return k;}char **analize(const char *input) //分析键入的命令,获取命令和参数并保存在arg中{ int number(const char *input); //分析命令和参数数量,来划分相应字符串 int i,j,k; //k记录命令和参数数量 int input_len; int is_back=0; char *buffer; char **arg;//存放命令及相应参数 input_len=strlen(input); if((buffer=(char *)malloc((input_len+1)*(sizeof(char))))==0) { fprintf(stderr,"error! can't malloc enough space for buffer\n"); return NULL; } //分析命令和参数数量 k=number(input); if((arg=(char **)malloc((k+1)*sizeof(char *)))==0) { fprintf(stderr,"error! can't malloc enough space for arg\n"); return NULL; } //将输入命令划分为相应命令和参数 for (i=0,j=0,k=0;i<=input_len;i++) { if(input[i]==' '||input[i]=='<'||input[i]=='>'||input[i]==' '||input[i]=='\0') { if(j == 0) /*这个条件可以略去连在一起的多个空格或者TAB */ continue; else { buffer[j] = '\0'; j++; arg[k] = (char *)malloc(sizeof(char)*j); /* 将指令或参数从缓存拷贝到arg中*/ strcpy(arg[k], buffer); j=0; /* 准备去下一个参数*/ k++; } } else { /* 如果字符串最后是 '&',则置后台运行标记为 1 */ if(input[i]== '&' && input[i+1]=='\0') { is_back = 1; continue; } buffer[j]=input[i]; j++; } } /* 在使用exec执行命令的时候,最后的参数必须是NULL指针,所以将最后一个参数置成空值*/ arg[k]=NULL; //释放申请空间 free(buffer); return arg;}char *read_order(char *buffer) //从键盘中读取命令{ char lc_char; char *input; int input_lenth=0; lc_char = getchar(); while(lc_char != '\n' && input_lenth < BUFFERSIZE) { buffer[input_lenth] = lc_char; lc_char = getchar(); input_lenth++; } if(input_lenth >= BUFFERSIZE) //超过允许缓冲区最大长度则抱错退出 { fprintf(stderr,"Your command too long ! Please reenter your command !\n"); input_lenth = 0; /* Reset */ return NULL; } else buffer[input_lenth] = '\0'; //加上串结束符,形成字符串 if((input=(char *)malloc(sizeof(char)*(input_lenth+1)))==0) { fprintf(stderr,"error! can't malloc enough space for input\n"); return NULL; } strcpy(input, buffer); return input;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -