为什么execvp()使用fork()执行两次?

我正在实现一个shell。

当尝试执行除了改变目录以外的命令时, execvp()运行,子程序终止,并创build一个新的子程序。 当我改变目录时,孩子不会终止,并创build一个新的孩子。 这是我的代码示例:

 for(;;) { printf("bash: "); parse(); ... pid_t pid = fork() if (pid == 0) if (!strcmp(line[0], "cd")) if (!line[1]) (void) chdir(getenv("HOME")); else (void) chdir(line[1]); else execvp(line[0], line); ... if (pid > 0) { while (pid == wait(NULL)); printf("%d terminated.\n", pid); } } 

cd ../; ls; 运行正确,除了我必须Ctrl+D两次结束程序。

虽然,如果我input相同的信息(即mybash < chdirtest ),它会正确运行一次,终止子mybash < chdirtest ,再次运行,除了在原来的直接,然后终止最后的孩子。

cd不应该通过子进程调用,shell本身应该改变它的当前目录(这是内部命令的属性:修改shell本身的进程)。

(primitve)外壳应该看起来像:

 for(;;) { printf("bash: "); parse(); // realize internal commands (here "cd") if (!strcmp(line[0], "cd")) { if (!line[1]) (void) chdir(getenv("HOME")); else (void) chdir(line[1]); continue; // jump back to read another command } // realize external commands pid_t pid = fork() if (pid == 0) { execvp(line[0], line); exit(EXIT_FAILURE); // wrong exec } // synchro on child if (pid > 0) { while (pid == wait(NULL)); printf("%d terminated.\n", pid); } }