📄 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 + -