C语言用fork+execlp实现minishell时进程顺序及退出值异常问题
问题根因
你的代码核心问题是搞反了fork()返回值对应的父子进程逻辑,同时存在系统调用参数错误、无错误处理的问题,具体问题拆解如下:
fork()返回值为0时代表当前处于子进程上下文,返回值大于0时才是父进程,返回值就是创建的子进程PID。你现在的逻辑是父进程直接调用execlp替换为/bin/sh执行命令,子进程反而在执行等待逻辑,完全和预期逻辑相反。- 子进程中调用
waitpid(pid, &wstatus, 0)时,子进程上下文里的pid变量值为0,waitpid(0)的语义是等待当前进程所在进程组的任意子进程退出,但子进程自身没有创建任何子进程,该调用会直接失败,你读取的wstatus是未初始化的栈垃圾值,所以输出的退出码85是无效值。 - 父进程被替换为
/bin/sh、子进程执行打印是两个独立的调度单元,两者的输出顺序完全由系统调度决定,这就是Hello出现在退出状态之后的原因。
修正后代码
#include <sys/wait.h> #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <err.h> #include <errno.h> int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Invalid number of arguments.\n"); return 1; } int pid = fork(); if (pid == -1) { err(1, "fork failed"); } else if (pid == 0) { // 子进程:执行传入的命令 execlp("/bin/sh", "sh", "-c", argv[1], NULL); // execlp只有执行出错才会返回 err(1, "exec failed"); } else { // 父进程:等待子进程退出后打印状态 int wstatus; if (waitpid(pid, &wstatus, 0) == -1) { err(1, "waitpid failed"); } printf("process exit status: %d\n", WEXITSTATUS(wstatus)); } return 0; }
验证输出
执行./main 'echo Hello'会得到预期结果:
Hello process exit status: 0
内容的提问来源于stack exchange,提问作者user17203867
相关产品推荐
相关产品推荐

