如何在 C 中使用 fork?

How to use fork in C?

完整代码如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
    char *command, *infile, *outfile;
    int wstatus;

    command = argv[1];
    infile = argv[2];
    outfile = argv[3];

    if (fork()) {
        wait(&wstatus);
        printf("Exit status: %d\n", WEXITSTATUS(wstatus));
    }
    else {
        close(0);
        open(infile, O_RDONLY);
        close(1);
        open(outfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);
        execlp(command, command, NULL);

    }

    return 0;
}


此代码应使用 stdinstdout 重定向分叉并执行命令,然后等待它执行终止并收到 printf WEXITSTATUS(wstatus)。例如./allredir hexdump out_of_ls dump_file.

所以,fork()之前的我都明白了。但是我有以下问题:

  1. 据我所知,fork() 克隆了进程,但是我不明白它是如何执行命令的,因为 execlp 应该这样做,而代码永远不会到达那部分。
  2. 我不明白 execlp 是如何工作的。为什么我们向它发送命令两次 (execlp(command, command, NULL);)?
  3. 如果我们不通过 outfile 无处可去,execlp 如何知道将输出重定向到哪里。
  4. 如果命令已经作为另一个参数传递,为什么我们还需要 infile

提前感谢您的回答。

  1. As far as I understand, fork() clones the process, however I do not understand how it executes the command, because execlp should do that and code never reaches that part.

分叉 returns 父进程 space 中子进程的 pid 和新进程 space 中的 0。子进程调用 execlp。

if (fork()) { 
    /* Parent process waits for child process */
}
else {
    /* Son process */
    execlp(command, command, NULL);
}

  1. I do not get how execlp works. Why do we send a command to it twice (execlp(command, command, NULL);)?

阅读 execlp man page and 话题

The first argument, by convention, should point to the filename associated with the file being executed.


  1. How does execlp know where to redirect the output if we do not pass outfile nowhere.

重定向发生在关闭 stdin 和 stdout 文件描述符之前。重定向是通过打开文件描述符将容纳条目 0 和 1 的文件来实现的。

else {
    /* redirecting stdin */
    close(0); 
    open(infile, O_RDONLY);  

    /* redirecting stdout */
    close(1); 
    open(outfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);

    execlp(command, command, NULL);
}

  1. Why do we even need an infile if the command is already passed as the other argument?

如果不查看作为命令传递的参数,我们无法判断您的程序做了什么。