【问题标题】:C Pipe to STDIN of another program and execlC管道到另一个程序的STDIN并执行
【发布时间】:2017-11-18 21:43:12
【问题描述】:

不明白为什么execl-command中的程序没有得到父进程的输入:

我的代码:(我删除了错误处理和其他一些步骤以使其更简单)

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
     int pipefd[2];
     pipe(pipefd);
     pid_t pid = fork();
     switch(pid){
         case -1:
             exit(EXIT_FAILURE);
         case 0:
             close(pipefd[1]);
             dup2(pipefd[0], STDIN_FILENO);
             close(pipefd[0]);
             execl("/usr/bin/wc", "-w", NULL);
             fflush(stdout);
             exit(EXIT_SUCCESS);
         default:
             close(pipefd[0]);
             FILE *pipewrite = fdopen(pipefd[1], "w");
             char *ar[] = {"W1", "W2", "W3", "W4", "W5"};
             for(int i = 0; i < 5; i++){
                 fputs(ar[i], pipewrite);
                 fflush(pipewrite);
             }
             fflush(pipewrite);
             fclose(pipewrite);
     }
     exit(EXIT_SUCCESS);
}

如果我启动程序,输出应该是 5。

【问题讨论】:

    标签: c pipe fork


    【解决方案1】:

    execl 调用有问题。

    这个

    execl("/usr/bin/wc", "-w", NULL);
    

    需要:

    execl("/usr/bin/wc", "wc", "-w", NULL);
    

    也就是说,您还需要将命令 (wc) 作为参数传递给 execl

    您将看到的下一个问题是wc 不是 5。这是因为您从父进程传递的所有标准输入内容都被视为单个单词(由于缺少空格)。 基本上,如果你这样做:

       fputs(ar[i], stdout);
    

    在父进程中,stdout 上看到的就是子进程看到的。

    以某种方式添加空格。例如,您可以再次拨打fputs

       fputs(ar[i], pipewrite);
       fputs(" ", pipewrite);
    

    或者,您可以在字符串中包含空格:

    char *ar[] = {"W1 ", "W2 ", "W3 ", "W4 ", "W5"};
    

    【讨论】:

    • 也可以使用fprintf(pipewrite, "%s\n", ar[i]);
    • 好主意。节省了对 fputs 的额外呼叫。
    • 好的,谢谢,这行得通。但是如果我在 shell 中运行程序,则 5 被设置为下一个命令的输入。 user@pc:~$ ./dsort user@pc:~$ 5 五个后面还有空格?
    • 这可能是你没有收获子进程。即 wait(NULL); 在 main 结束时在 exit(EXIT_SUCCESS); 之前调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多