⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xie(shell).c

📁 一个简单的关于LINUX下的模仿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 + -