【问题标题】:Why does using process substitution here cause a hang?为什么在这里使用进程替换会导致挂起?
【发布时间】:2026-01-28 05:40:01
【问题描述】:

我有一个程序需要启动其他程序,可能用文件和管道替换它们的标准输入输出。虽然它似乎“工作”,因为子进程确实从源管道获取它的 I/O,但不幸的是,它也会导致挂起。子进程似乎永远不会得到EOF

这是代码的最小复制,为什么在打印"Hello World\n"后会挂起?

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

int main(int argc, char *argv[]) {

    switch (pid_t pid = fork()) {
    case 0: {
        // in child

        // replace the child's stdin with whatever filename is given as argv[1]
        freopen(argv[1], "r+b", stdin);

        // construct an argv array for to exec, no need for anything except 
        // argv[0] since we want it to use stdin
        char path[]  = "/bin/cat";
        char *args[] = {path, NULL};

        // run it!
        execv(args[0], args);
        abort(); // we should never get here!
    }
    case -1:
        // error
        return -1;
    default: {
        // in parent, just wait for the sub-process to terminate
        int status;
        const auto r = waitpid(pid, &status, __WALL);

        if (r == -1) {
            perror("waitpid");
            return -1;
        }
        break;
    }
    }
}
# runs printf creating a pipe, which is then passed as the argv of my test program
./test >(printf "Hello\n")

【问题讨论】:

    标签: c++ linux bash shell process-substitution


    【解决方案1】:
    ./test <(printf "Hello\n")
    

    切换到&gt;(...)&lt;(...) 以从printf 读取而不是写入。

    freopen(argv[1], "rb", stdin);
    

    不要使用r+。您只是从文件中读取,所以将其设为r

    【讨论】:

      最近更新 更多