while(1)
- 作为一个始终运行的shell, 其是运行在一个死循环中的。也就是通过
while(1)
来实现,并且通过exit
实现while(1){ if(strcmp(buff,"exit")){ break; } } ...... exit(0)
内置命令和子程序命令
-
shell中的命令大致可以分为两种,即内置命令和子程序命令
- 内置命令即是在父程序中执行包括 cd, exit
- 子程序命令即通过fork+execl创建的子程序运行的命令,运行它们的shell作为其父程序。
-
在shell框架中,可以将内置命令放在父程序的代码中,直接运行。子程序命令则通过封装来进行调用
获取命令
- 命令获取由用户在屏幕上进行输入,所以我们可以使用fget()实现
- 同时因为fget()自带一个换行,所以,我们还要对最后一个字符进行处理,代码如下:
char buff[BUFF_SIZE]; fgets(buff,128,stdin); buff[strlen(buff)-1]='\0';
- 此外我们还有其他的方案解决,其中有一种可以实现历史命令的查看:
Step 2:libreadline [myshell_project] - CSDN App
分割命令
- 获取用户的输入之后,我们还需要对命令进行分割,从而确保命令可以被解读,这时候我们可以使用strtok()函数。
- 此外对于这个函数,我们应当将其封装调用。
char* get_cmd(char* buff, char * myargv[]){ char *s = strtok(buff," ");//第一次调用 int i=0; while(s!=NULL){ myargv[i++]=s; s = strtok(NULL," ");//循环后续调用 } return myargv[0]; }
判断命令
- 若输入的是内置命令,则在当前循环解决
- 若是子程序命令,则在封装函数解决
- 若什么都没输入,则使用continue退出
框架代码
#include <stdio.h>
#include <stlib.h>
//#include <readline/readline.h>
//#include <readline/history.h>
int main(){
while(1){
char *folders[BUFF_SIZE];//将当前位置按文件名存入数组
show(folders);//显示命令行
//获取命令
char buff[BUFF_SIZE];
fgets(buff,128,stdin);
buff[strlen(buff)-1]='\0';
char *myargv[ARG_MAX]={0};
char *cmd = get_cmd(buff, myargv);
//分割命令
char *myargv[ARG_MAX]={0};
char *cmd = get_cmd(buff, myargv);
//strcpy(buff,readline());//readline中可填写内容,内容将被打印出来
//add_history(buff);
//判断命令
if(cmd==NULL){
continue;
}else if(strcmp("cmmond",cmd)==0){
cmmond_cmd(myargv);
}else if(strcmp(cmd,"exit")==0){
break;
}else{
other_cmd(cmd,myargv);
}
}
//退出
exit(0);
}