《Unix/Linux編程實踐教程》是一本學習系統編程非常好的入門教材。本書第8章開始介紹進程的相關概念。包括相關的命令如ps,以及相關的系統調用如fork,wait等。在本章中,作者通過一步步搭建自己的Shell來講解unix的進程模型。
相關閱讀:
《Unix/Linux編程實踐教程》之Shell編程一 http://www.linuxidc.com/Linux/2012-12/75690.htm
《Unix/Linux編程實踐教程》之Shell編程二 http://www.linuxidc.com/Linux/2012-12/75691.htm
《Unix/Linux編程實踐教程》之管道 http://www.linuxidc.com/Linux/2012-12/75692.htm
Unix/Linux編程實踐教程【高清PDF中文版+附錄光盤+代碼】:http://www.linuxidc.com/Linux/2011-08/41374.htm
為了搭建一個shell,需要學會以下技術:
1)運行一個程序(execvp);
2)建立一個進程(fork);
3)等待退出(wait)。
例子代碼如下:
1: /* prompting shell version 1
2: * Prompts for the command and its arguments.
3: * Builds the argument vector for the call to execvp.
4: * Uses execvp(), and never returns.
5: */
6:
7: #include <stdio.h>
8: #include <signal.h>
9: #include <string.h>
10:
11: #define MAXARGS 20 /* cmdline args */
12: #define ARGLEN 100 /* token length */
13:
14: int main()
15: {
16: char *arglist[MAXARGS+1]; /* an array of ptrs */
17: int numargs; /* index into array */
18: char argbuf[ARGLEN]; /* read stuff here */
19: char *makestring(); /* malloc etc */
20:
21: numargs = 0;
22: while ( numargs < MAXARGS )
23: {
24: printf("Arg[%d]? ", numargs);
25: if ( fgets(argbuf, ARGLEN, stdin) && *argbuf != '/n' )
26: arglist[numargs++] = makestring(argbuf);
27: else
28: {
29: if ( numargs > 0 ){ /* any args? */
30: arglist[numargs]=NULL; /* close list */
31: execute( arglist ); /* do it */
32: numargs = 0; /* and reset */
33: }
34: }
35: }
36: return 0;
37: }
38:
39: int execute( char *arglist[] )
40: /*
41: * use execvp to do it
42: */
43: {
44: execvp(arglist[0], arglist); /* do it */
45: perror("execvp failed");
46: exit(1);
47: }
48:
49: char * makestring( char *buf )
50: /*
51: * trim off newline and create storage for the string
52: */
53: {
54: char *cp, *malloc();
55:
56: buf[strlen(buf)-1] = '/0'; /* trim newline */
57: cp = malloc( strlen(buf)+1 ); /* get memory */
58: if ( cp == NULL ){ /* or die */
59: fprintf(stderr,"no memory/n");
60: exit(1);
61: }
62: strcpy(cp, buf); /* copy chars */
63: return cp; /* return ptr */
64: }
65:
該程序通過終端接收命令參數, 通過makestring()將'/n’換成'/0',之後存入arglist數組,當輸入完成後,在數組最後添加0。最後調用execute()執行。
需要注意的是:如果執行成功,execvp沒有返回值,當前程序從進程中清除。
運行後的結果如下:
可以看到,“ls -l” 命令可以成功運行。但存在一個顯著的缺陷:程序只能運行一次,不能像一般的shell一樣,可以一直等待用戶輸入,然後執行。