实现带参数的简单shell(unix操作系统系)--1
实现带参数的简单shell
调用系统函数:
int execve(const char *path, const char *argv[],const char *envp[]);
函数说明:
path:要执行的程序路径名,比如“/bin/ls”,“cd”,“/usr/bin/gcc”等等。
argv:参数表,比如ls命令中可带的命令行参数-l,-a等。注意,argv的第一个元素必须是要执行的程序(命令)的路径名。
envp:环境变量表,供要执行的命令使用。实参数用NULL或系统环境变量environ均可。
注意,因为environ由系统提供,属于外部变量,所以说明时必须用“extern”修饰。
实例:
char *argv[] = {“gcc”, “-g”, “-c”, “hello.c”, NULL}; execve(“/usr/bin/gcc”, argv, environ); // 编译程序“hello.c”
说明(使用到的文件):
Apue.h 为头文件 。
Error2e.c 为错误处理。
Shell2.c 为源文件。
Shell2 可执行文件。
#include "apue.h" #include <sys/wait.h> #include "string.h" static void sig_int(int); /* our signal-catching function */ int main(void) { char buf[MAXLINE]; /* from apue.h */ pid_t pid; int status; //my write char* argv[MAXLINE]; int len=0; int j=1; int i=0; if (signal(SIGINT, sig_int) == SIG_ERR) err_sys("signal error"); printf("%% "); /* print prompt (printf requires %% to print %) */ while (fgets(buf, MAXLINE, stdin) != NULL) { if(buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]='\0'; //my write /*for(i=0;i<10;i++) { argv[i]=NULL; }*/ len=strlen(buf); for(i=0;i<len;i++) if(buf[i]==' ') buf[i]='\0'; argv[0]=buf; for(i=0;i<len;i++) { if(buf[i]=='\0') argv[j++]=&buf[i+1]; } argv[j]=NULL; j=1; //end /* if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0; */ /* replace newline with null */ if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { /* child */ //my write printf("now len:%d agrv[n]:0:%s 1:%s 2:%s 3 %s 4 %s 5 %s ",len,argv[0],argv[1],argv[2],argv[3],argv[4],argv[5]); execve(argv[0], argv, NULL); err_ret("couldn't execute: %s", buf); exit(127); } /* parent */ if ((pid = waitpid(pid, &status, 0)) < 0) err_sys("waitpid error"); printf("%% "); } exit(0); } void sig_int(int signo) { printf("interrupt\n%% "); }
运行结果: