📄 xie(shell).c
字号:
#include<stdio.h>#include<errno.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/wait.h>#include<unistd.h>#include<fcntl.h>#define TRACE printf("%s @ %u\n",__FILE__,__LINE__)int main(int argc,char *argv[],char *env[]){ char buf[256],*cmd,*vec[128],path[50]; int cComLine,cBegin,i,j,output,k,status,signal; //用j记录下buf中的字符书目,output用在echo中,i,k用在environ中, for(;;) { printf("@>>"); if(fgets(buf,sizeof(buf),stdin)==NULL)break; for(j=0;buf[j]!='\0';j++); //用j记录下buf中的字符书目,为echo输出施用 cmd=strtok(buf," \t\n"); //解析输入的命令 ,注意要加上\n,可能是由于输完命令的回车也被存入了buf中导 致回车放到了cmd里面去了,使得cmd!=exit了. if(cmd) { if(strcmp(cmd,"exit")==0||strcmp(cmd,"quit")==0||strcmp(cmd,"bye")==0)exit(0); if(strcmp(cmd,"help")==0) { printf("Introductian:\n"); printf("1.cd,echo,help,exit,environ are the inside commands\n"); printf("2.Besure your command is separated by blank or table\n"); printf("thank you for useing!\n"); continue; } if(strcmp(cmd,"echo")==0) { //输入缓冲区buf中第一个有效单词肯定是echo cBegin=0; while(buf[cBegin]!='e')cBegin++; for(output=cBegin+4;output<=j;output++) //puts会多输出个回车 printf("%c",buf[output]); continue; } if(strcmp(cmd,"jobs")==0) { system("ps -A"); continue; } if(strcmp(cmd,"environ")==0) { for(i=0;env[i];i++) printf("ENV %d: %p [%s]\n",i,env[i],env[i]); continue; } cComLine=0; vec[cComLine++]=cmd; while(vec[cComLine++]=strtok(NULL," \t\n")); //将输入命令的参数方到数组vec[]中去 cComLine=1; //分析命令行参数的最后有无&,有则将信号量signal置1, while(vec[cComLine]!=NULL)cComLine++; //并将&去掉,以免导致参数出错,利用signal控制wait()的 if(*vec[cComLine-1]=='&'){signal=1; vec[cComLine-1]=NULL;} //开关 if(strcmp(cmd,"cd")==0) { if(vec[1]==NULL) //列出当前工作目录 { if(!getcwd(path,sizeof path)) {perror("getcwd():");continue;} else {printf("cwd='%s'\n",path);continue;} } else //修改当前目录,从vec[1]开始存放的是参数, { //strcpy(path,&vec[1]); cComLine=1; k=0; while(vec[cComLine]!=NULL) //将命令行参数依次组合起来放在path中 { i=strlen(vec[cComLine]) ; strcpy(&path[k],vec[cComLine++]); k=k+i+1; } if(chdir(path)!=0) {perror("cannot cd:");continue;} } continue; } if (strcmp(cmd,"shell")==0) { int fd; char iobuf[1024]; char *cmd1; if((fd=open(vec[1],O_RDONLY,0))==-1) {perror("open error");exit(2);} if(read(fd,iobuf,1024)==-1) {perror("read error");continue;} cmd1=strtok(iobuf,"\n"); while(cmd1!=NULL) { system(cmd1); cmd1=strtok(NULL,"\n"); } close(fd); exit(0); } if(fork()==0) { //for(status=0;status<10000;status++)TRACE;//增加延时使子进程后完成调试时可以测试父子进程是否是并发的 execvp(cmd,vec); perror("ERROR"); exit(0); } if(signal!=1) wait(&status); //如果signal!=1父进程会在子进程结束后才重新循环输出提示符 //反之则有可能新的提示符被子进程的输出淹没, //虽然没有提示符实际上shell已经在等待新的输入 } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -