简体   繁体   English

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

[英]Why is execvp() executing twice using fork()?

I am implementing a shell. 我正在实现一个外壳。

When attempting a command other than changing directories, execvp() runs, the child terminates and a new child is created. 当尝试更改目录以外的命令时, execvp()运行,该子级终止并创建一个新的子级。 When I change directories, the child does not terminate and a new child is created. 当我更改目录时,该子级不会终止,并且会创建一个新的子级。 Here is a sample of my code: 这是我的代码示例:

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; runs correctly, except I have to Ctrl+D twice to end the program. 运行正常,除了必须两次Ctrl+D结束程序。

Though, if I pipe the same information (ie. mybash < chdirtest ), it runs correctly once, terminates the child, runs again except in the original directly, then terminates the final child. 但是,如果我传递相同的信息(即mybash < chdirtest ),则它将正确运行一次,终止子项,直接在原始文件中再次运行,然后终止最终子项。

cd should not be invoked through a child process, the shell itself should change its current directory (that's the property of an internal command: modify the process of the shell itself). 不应通过子进程调用cd ,shell本身应更改其当前目录(这是内部命令的属性:修改shell本身的进程)。

A (primitve) shell should looks like: (primitve)shell应该看起来像:

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM