本文共 3052 字,大约阅读时间需要 10 分钟。
Shell命令在是最常用的一个和操作系统交互的工具。
shell命令的基本执行过程是:
1)从stdin来读取用户的command。
2)对command进行解析,并判断是否为buildin command
3)如果是buildin command则执行buildin command
4)如果非buildin command,则执行fork命令,然后在fork的子进程中执行execve创建新的program。
其中还涉及到对输入command进行parse的简单过程。
5)如果要对进程的切换fg, bg等。需要涉及到signal切换等。(暂时不支持)
一下是一个最简单的shell, 依赖书籍csapp.c 以及 csapp.h
/* Simple Shell command * linux>gcc -o shellex shellex.c csapp.c -lpthread*/#include "csapp.h"#define MAXARGS 128/*Function prototypes */void eval(char *cmdline);int parseline(char * buf, char **argv);int builtin_command(char **argv);int main(){ char cmdline[MAXLINE]; /* Command line */ while(1) { /* Read */ printf("> "); Fgets(cmdline, MAXLINE, stdin); if(feof(stdin)) exit(0); /* Evaluate */ eval(cmdline); }}/* eval - Evaluate a command line */void eval(char *cmdline){ char *argv[MAXARGS]; /* Argument list execve() */ char buf[MAXLINE]; /* Holds modified command line */ int bg; /* Should the job run in bg or fg? */ pid_t pid; /* Process id */ strcpy(buf, cmdline); bg = parseline(buf, argv); if(argv[0] == NULL) return; /* Ignore empty lines */ if(!builtin_command(argv)) { if((pid = Fork()) == 0) { /* Child runs user job */ if(execve(argv[0], argv, environ) < 0) { printf("%s: Command not found.\n", argv[0]); exit(EXIT_SUCCESS); } } /* Parent waits for foreground job to terminate */ if(!bg) { int status; if(waitpid(pid, &status, 0) < 0) unix_error("waitfg: waitpid error"); } else { printf("%d %s", pid, cmdline); } } return;}/* If first arg is a builtin command, run it and return true */int builtin_command(char **argv){ if(!strcmp(argv[0], "quit")) /* quit command */ exit(EXIT_SUCCESS); if(!strcmp(argv[0], "&")) /* Ignore singleton & */ return 1; return 0; /* Not a builtin command */}/* parseline - Parse the command line and build the argv array */int parseline(char *buf, char ** argv){ char * delim; /* Points to first space delimiter */ int argc; /* Number of args */ int bg; /* Background job? */ buf[strlen(buf) - 1] = ' '; /* Replace trailing '\n' with space */ while(*buf && (*buf == ' ')) /* Ignore leading spaces */ buf++; /* Build the argv list */ argc = 0; while((delim = strchr(buf, ' '))) { argv[argc++] = buf; *delim = '\0'; buf = delim + 1; while(*buf && (*buf == ' ')) /* Ignore spaces */ buf++; } argv[argc] = NULL; if(argc == 0) /* Ignore blank line */ return 1; /* Should the job run in the background? */ if((bg = (*argv[argc - 1] == '&')) != 0) argv[--argc] = NULL; return bg;}
执行最简单的命令:
转载地址:http://xwwci.baihongyu.com/