目的:我们要用c语言编写一个shell可以运行在linux机器上的。
介绍:shell所在的层次
我们要做的是操作系统,用于用户与操作系统进行交互的myhsell
思路:用户输入 一行字符串,我们先将其进行切割为一段段的字符串,然后一一匹配判断是内置命令还是 外置命令。内置命令是写在shell程序里面的,而外置命令是单独写的程序,用exec族系统调用。
好,那么下面我们看代码:
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<sys/wait.h> 4 #include<stdlib.h> 5 #include<pwd.h> 6 #include<string.h> 7 #define MAX_CMD 255 8 #define MAX_DIR_NAME 255 9 10 //help帮助文档 11 int helps(char *inputs[],int i){ 12 if(i==1){ 13 printf("These shell commands are defined internally. Type 'help' to see this list. "); 14 printf("Type 'help name' to find out more about the function 'name' "); 15 return 1; 16 } 17 else if (strcmp(inputs[1],"pwd")==0){ 18 printf("pwd:打印当前绝对路径 "); 19 return 1; 20 }else if(strcmp(inputs[1],"cd")==0){ 21 printf("cd:可以切换当前目录 "); 22 return 1; 23 } else if(strcmp(inputs[1],"exit")==0){ 24 printf("exit:退出shell "); 25 return 1; 26 } else if(strcmp(inputs[1],"echo")==0){ 27 printf("echo:显示并换行 "); 28 return 1; 29 } 30 return 0; 31 } 32 33 34 35 //编写一个外置命令函数专门写内置指令 36 //返回值为1时为成功执行外置指令 37 //返回0时为执行失败不是外置命令 38 int build_out_command(char *inputs[],int i){ 39 char path[]="/root/Desktop/codec/myshell/"; 40 char buffer[10]; 41 bzero(buffer,10); 42 int fd[2]; 43 if(pipe(fd)==-1){ 44 return 0; 45 } 46 int rc=fork(); 47 if(rc<0){ 48 return 0; 49 } 50 else if(rc==0){ 51 //关掉读 52 close(fd[0]); 53 if(execv(strcat(path,inputs[0]),inputs)<0){ 54 write(fd[1],"false",10); 55 }else{ 56 write(fd[1],"true",10); 57 } 58 close(fd[1]); 59 exit(0); 60 //结束子进程 61 }else if(rc>0){ 62 close(fd[1]); 63 wait(NULL); 64 read(fd[0],buffer,10); 65 if(strcmp(buffer,"false")==0){ 66 return 0; 67 }else{ 68 return 1; 69 } 70 } 71 } 72 73 74 75 76 //编写一个内置命令函数专门写内置指令 77 //返回值为1时为成功执行内置指令 78 //返回0时为不是内置命令 79 int build_in_command(char cmdstring[],char *inputs[],int i){ 80 //1.实现exit退出 81 //printf("inputs[0]=%s",inputs[0]); 82 if(strcmp(inputs[0],"exit")==0){ 83 printf("Bye. "); 84 exit(0); 85 } 86 //2.实现pwd返回目录 87 else if(strcmp(inputs[0],"pwd")==0){ 88 char path[MAX_DIR_NAME]; 89 memset(path,0,MAX_DIR_NAME); 90 printf("%s ",getcwd(path,MAX_DIR_NAME)); 91 return 1; 92 } 93 //3.实现cd改变目录 94 else if(strcmp(inputs[0],"cd")==0){ 95 if(chdir(inputs[1])==0){ 96 return 1; 97 } 98 99 } 100 //4.echo显示并换行 101 else if(strcmp(inputs[0],"echo")==0){ 102 char *buf1=cmdstring; 103 while(*buf1==' '){ 104 buf1++; 105 } 106 while(*buf1!=' '){ 107 buf1++; 108 } 109 while(*buf1==' '){ 110 buf1++; 111 } 112 113 printf("%s ",buf1); 114 return 1; 115 116 } 117 //help帮助文档 118 else if(strcmp(inputs[0],"help")==0){ 119 int i1= helps(inputs,i); 120 return i1; 121 } 122 123 124 125 return 0; 126 } 127 128 129 struct passwd *pwd1; 130 pwd1=getpwuid(getuid()); 131 char path[MAX_DIR_NAME]; 132 memset(path,0,MAX_DIR_NAME); 133 getcwd(path,MAX_DIR_NAME); 134 int i=0; 135 int len=strlen(path); 136 char *p=path; 137 138 int i1=len; 139 for(i1;i1>=0;i1--){ 140 if(path[i1]=='/'){ 141 path[i1]='