源代码1:exec1
1 #include "apue.h"
2 #include <sys/wait.h>
3
4 char *env_init[] = { "USER=unknown", "PATH=/tmp", NULL };
5
6 int
7 main(void)
8 {
9 pid_t pid;
10
11 if ((pid = fork()) < 0) {
12 err_sys("fork error");
13 } else if (pid == 0) { /* specify pathname, specify environment */
14 if (execle("/home/user/project_UNIX/project_test/ch8_8/test.shell", " ", "myarg1",
15 "MY ARG2", (char *)0, env_init) < 0)
16 err_sys("execle error");
17 }
18
19 if (waitpid(pid, NULL, 0) < 0)
20 err_sys("wait error");
21
22 if ((pid = fork()) < 0) {
23 err_sys("fork error");
24 } else if (pid == 0) { /* specify filename, inherit environment */
25 if (execlp("./test.shell", " ", "only 1 arg", (char *)0) < 0)
26 err_sys("execlp error");
27 }
28
29 if (waitpid(pid, NULL, 0) < 0)//等待子进程2
30 err_sys("wait error");
31
32 exit(0);
33 }
第14行和第25行的arg0之所以可以用空格代替的原因是:一般而言,pathname包含了比第一个参数更多的信息。(UNIX高级编程第二版P197)
第25行说明:因为不能期望该解释器(该例子中为/home/user/project_UNIX/project_test/ch8_8/echoall.out(见下面的解释器文件))会使用PATH变量定位该解释器文件,所以只传送其路径名中的文件名是不够的,所以要将解释器文件完整的路径名传送给解释器。
源代码2:echoall.c
1 #include "apue.h"
2
3 int
4 main(int argc, char *argv[])
5 {
6 int i;
7 char **ptr;
8 extern char **environ;
9
10 for (i = 0; i < argc; i++) /* echo all command-line args */
11 printf("argv[%d]: %s\n", i, argv[i]);
12
13 for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */
14 printf("%s\n", *ptr);
15
16 exit(0);
17 }
源代码3:解释器文件test.shell
1 #! /home/user/project_UNIX/project_test/ch8_8/echoall.out foo
注意生成的test.shell文件必须增加为可执行文件。echoall.out是echoall.c生成的可执行文件(见下面的makefile)。
源代码4:makefile
1 ch8_8.out: exec1.o
2 gcc -o ch8_8.out exec1.o
3 echoall.out: echoall.o
4 gcc -o echoall.out echoall.o
5 exec1.o: exec1.c
6 gcc -g -c exec1.c -o exec1.o
7 echoall.o: echoall.c
8 gcc -g -c echoall.c -o echoall.o
9 clean:
10 rm *.o *.out
在终端执行:
$make ch8_8.out
$make echoall.out
$./ch8_8.out
结果如下:
[user@localhost ch8_8]$ ./ch8_8.out
argv[0]: /home/user/project_UNIX/project_test/ch8_8/echoall.out
argv[1]: foo
argv[2]: /home/user/project_UNIX/project_test/ch8_8/test.shell
argv[3]: myarg1
argv[4]: MY ARG2
USER=unknown
PATH=/tmp
argv[0]: /home/user/project_UNIX/project_test/ch8_8/echoall.out
argv[1]: foo
argv[2]: ./test.shell
argv[3]: only 1 arg
ORBIT_SOCKETDIR=/tmp/orbit-user
HOSTNAME=localhost.localdomain
IMSETTINGS_INTEGRATE_DESKTOP=yes
TERM=xterm
SHELL=/bin/bash
...此处省略...行
OLDPWD=/home/user/project_UNIX/project_test