shell是Unix/Linux中的重要工具,用来解析用户输入的命令。下面我们来实现一个简单的shell程序,来练习fork/exec/wait/exit的使用,顺便推荐一本书籍《Understanding Unix/Linux Programming - A Guide to Theory and Practice》,这本书写的非常好,适合Unix/Linux系统编程初学者使用。
下面是我们shell的主程序:
int main(void) { char *cmdline; char *prompt; char **arglist; int result; prompt = PROMPT; signal(SIGINT, SIG_IGN); signal(SIGQUIT,SIG_IGN); while ((cmdline = next_cmd(prompt, stdin)) != NULL) { if ((arglist = split_line(cmdline)) != NULL) { result = execute(arglist); freelist(arglist); } free(cmdline); } return ; }
其中,next_cmd()函数的主要功能是从输入流中读入下一个命令,碰到文件结束符返回NULL。下面是该函数的代码:
char *next_cmd(char *prompt, FILE *file) { char *cmdline; int length = ; int c; int location = ; printf("%s", prompt); while ((c = getc(file)) != '\n') { if (location + >= length) { cmdline = (char *)malloc(BUFSIZ); length = BUFSIZ; } else if (location >= BUFSIZ) { cmdline = realloc(cmdline, length + BUFSIZ); length += BUFSIZ; } cmdline[location++] = c; } cmdline[location] = '\0'; return cmdline; }
split_line()函数的主要功能是将输入的一行字符串拆解成字符串数组,该字符串数组以NULL结束。下面是该函数的代码:
char **split_line(char *cmd) { char **arglist; int row = ; int len = ; char *cp = cmd; char *start = cmd; arglist = malloc(BUFSIZ); while (*cp != '\0') { while (*cp != ' ' && *cp != '\t') { ++cp; ++len; } arglist[row] = malloc(len + ); strncpy(arglist[row], start, len); ++row; len = ; while (*cp == ' ' || *cp == '\t') { ++cp; } start = cp; } arglist[row] = NULL; return arglist; }
execute()函数的主要功能是使用fork, execvp和wait函数来运行一个命令,并返回命令的结束状态。下面该函数的代码:
int execute(char **argv) { pid_t pid; int child_info = -; if ((pid = fork()) == -) { perror("fork error"); } if (pid == ) { signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); execvp(argv[], argv); perror("exec error"); exit(); }else { if (wait(&child_info) == -) { perror("wait error"); } } return child_info; }
freelist()函数是释放上面分配的字符串数组的空间。下面是该函数的代码:
void freelist(char **list) { char **cp = list; while (*cp) { free(*cp); ++cp; } free(list); }
由于个人水平有限,欢迎讨论,非喜勿喷,thank you!!
以上就是[Linux]shell的简单实现的详细内容,更多关于[Linux]shell的简单实现的资料请关注九品源码其它相关文章!