/* chicken_sh.c * 破殼,小雞. * 增長了命令行處理,比egg_sh好用了 */ #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<signal.h> #include "smsh.h" #define DFL_PROMPT "> " void setup(); void fatal(char *s1, char *s2, int n) int main() { char *cmdline, *prompt, **arglist; int result; prompt = DFL_PROMPT; setup(); while ((cmdline = next_cmd(prompt, stdin)) != NULL) { if ((arglist = splitline(cmdline)) != NULL) { result = execute(arglist); freelist(arglist); } free(cmdline); } return 0; } void setup() /* 設置信號處理函數 */ { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); } void fatal(char *s1, char *s2, int n) /* 錯誤處理函數 */ { fprintf(stderr, "Error: %s, %s\n", s1, s2); exit(n); }
gcc -o chichen_sh chicken_sh.c splitline.c execute.c
/*splitline.c * 爲chicken_sh讀取並解析命令 *char *next_cmd(char *prompt, FILE *fp) 取下一條指令 *char **splitline(char *str); 解析字符串 */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include "chicken_sh.h" char *next_cmd(char *prompt, FILE * fp) { char *buf; int bufspace = 0; int pos=0; /* 當前位置 */ int c; printf("%s", prompt); while ((c = getc(fp)) != EOF) { /*若須要空間*/ if (pos + 1 >= bufspace) { if (bufspace == 0) buf = emalloc(BUFSIZ); else buf = erealloc(buf, bufspace + BUFSIZ); /* 擴大分配的內存 */ bufspace += BUFSIZ; } /* 命令結束 */ if (c == '\n') break; /* 若是不結束,則添加進緩衝區 */ buf[pos++] = c; } if (c == EOF && pos == 0) return NULL; buf[pos] = '\0'; return buf; } #define is_delim(x) ((x) == ' ' || (x) == '\t') /*參數分隔符是空格或tab*/ char *newstr(char *s, int l); char **splitline(char *line) { char **args; /*要返回的參數數組*/ int spots = 0; /*參數指針的容量*/ int bufspace = 0; /*緩衝空間*/ int argnum = 0; /*參數計數*/ char *cp = line; char *start; int len; if (line == NULL) /* 什麼輸入也沒有 */ return NULL; args = emalloc(BUFSIZ); /* 分配參數數組 */ bufspace = BUFSIZ; spots = BUFSIZ / sizeof(char *); while (*cp != '\0') { while (is_delim(*cp)) cp++; if (*cp == "\0") break; /* 確保參數數組的空間 */ if (argnum + 1 >= spots) { args = erealloc(args, bufspace + BUFSIZ); bufspace += BUFSIZ; spots += (BUFSIZ / sizeof(char *)); } /* 標記開始的地方,查找以\0 結束的位置 */ start = cp; len = 1; while (*++cp != '\0' && !(is_delim(*cp))) len++; args[argnum++] = newstr(start, len); } args[argnum] = NULL; return args; } /* * 構造字符串,以'\0' 結尾*/ char *newstr(char *s, int l) { char *rv = emalloc(l + 1); rv[l] = '\0'; strncpy(rv, s, l); return rv; } void freelist(char **list) /*參數用完後,釋放空間*/ { char **cp = list; while (*cp) free(*cp++); free(list); } void *emalloc(size_t n) { void *rv; if ((rv = malloc(n)) == NULL) fatal("out of memory", "", 1); return rv; } void *erealloc(void *p, size_t n) { void *rv; if ((rv = realloc(p, n)) == NULL) fatal("realloc() failed", "", 1); return rv; }
if cat hello.c then echo hello fi若是cat命令執行成功,返回0,那麼then到fi的語句塊就會執行。注意,命令返回0和直接在if後面敲個0是不一樣的,若是想直接說明真假,能夠用true和false, if true就至關與if後面跟了個執行成功的命令,false反之。 太長了,下一篇再寫...