程序试图实现的输出是什么

What is the output that the program trying to achieve

我知道 fork()、dup2 调用,但我无法推断程序的输出。

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>

int main (int argc, char *argv[]){
    pid_t pid1, pid2;
    int fds[2];

    char *argv1[] = { "ls", "-l","usr/bin", NULL};
    char *argv2[] = {"more", NULL};

    pipe(fds);

    pid1=fork();
    if(!pid1){
        close(fds[0]);
        dup2(fds[1], STDOUT_FILENO);
        close(fds[1]);
        execvp(argv1[0],argv1);
    }

    pid2=fork();
    if(!pid2){
        close(fds[1]);
        dup2(fds[0], STDOUT_FILENO);
        close(fds[0]);
        execvp(argv1[0],argv2);
    }

    close(fds[0]);
    close(fds[1]);
    waitpid(pid2,NULL,0);

    return EXIT_SUCCESS;

}

此外,如果我进行实验并在最后调用 waitpid 时错误地按 pid1 而不是 pid2 会发生什么情况。

名义上,程序是运行 shell 管道

ls -l usr/bin | more

在实践中,与 more 的连接处理不当(如果不进行所有必要的更改,使用复制和粘贴是危险的)。它将管道的读取端连接到 more 的标准输出,这简直是坏掉了。它还会第二次运行 ls(将 argv1[0] 传递给 execvp() 而不是 argv2[0]),但告诉 ls 它的名称是 more。它也不相信 execvp() 会失败——但它会失败。

有了这些最小的修复(程序不包括 <stdio.h> 所以没有错误报告),你会得到类似的东西:

#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    pid_t pid1, pid2;
    int fds[2];

    char *argv1[] = { "ls", "-l", "usr/bin", NULL };
    char *argv2[] = { "more", NULL };

    pipe(fds);

    pid1 = fork();
    if (pid1 == 0)
    {
        close(fds[0]);
        dup2(fds[1], STDOUT_FILENO);
        close(fds[1]);
        execvp(argv1[0], argv1);
        exit(EXIT_FAILURE);
    }

    pid2 = fork();
    if (pid2 == 0)
    {
        close(fds[1]);
        dup2(fds[0], STDIN_FILENO);
        close(fds[0]);
        execvp(argv2[0], argv2);
        exit(EXIT_FAILURE);
    }

    close(fds[0]);
    close(fds[1]);
    waitpid(pid2, NULL, 0);

    return EXIT_SUCCESS;
}

我调用了程序 pipe31(从 pipe31.c 创建)并得到示例输出:

$ pipe31
ls: usr/bin: No such file or directory
$ mkdir -p usr/bin
$ random -n 15 1000 9999 > usr/bin/polyglot
$ pipe31
total 8
-rw-r--r--  1 jonathanleffler  staff  75 Dec  8 22:07 polyglot
$

当如图所示调用时,本地 random 程序在 1000 到 9999 之间创建 15 个随机数,每个随机数在其自己的行上 — 对应于文件中的 75 个字节。输出是通过 more 传输的,但很难在网络浏览器中发现它。

至于你提议的实验——实验吧——你不会造成伤害。您看到的内容将取决于您正在使用的目录的大小,以及您的终端的大小 window。但是,如果 ls -l 的输出足够大(但不是太大),那么您会在 ls 列表的中间得到一个 shell 提示,并且您会more 显示数据并等待读取换行符。 shell 和 more 之间可能会就以下输入进行竞争,这可能会很有趣。这假设您在试验之前解决了其余答案中确定的问题。