当前位置: 首页 > 知识库问答 >
问题:

管道将一个程序的stdout重定向到另一程序的stdin

路伟
2023-03-14

我们必须编写一个 C 程序,该程序本质上将使用管道将一个命令/程序的 stdin 重定向到另一个命令/程序 stdout。如果命令行上的程序被传递了 ./a.out ls -l \; more,它应该将 ls -l 的 stdout 重定向到 more,其中 \; 是分隔符。这个程序应该适用于我们路径中的任何命令/程序,所以:./a.out cat filename.c \; more,应该与键入:cat filename.c |更多相同。

我的问题是,我的程序似乎不能正常执行,或者管道没有按预期工作。基本上,除了我放置的打印语句调试之外,我没有得到任何输出。具体来说,该程序输出:Exec...然后是错误,这些都在父代码中。

  #include <fcntl.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  void pipeit(char * pro1, char * pro2, char * p1args[], char * p2args[])
  {
     pid_t pid;
     int fd[2];
     int st;
     pipe(fd);
     pid = fork();

     if(pid < 0)
     {
        printf("Error Forking...\n");
        exit(-1);
     }
     else if(pid == 0)
     {
        dup2(fd[1],1);
        close(fd[0]);
        close(1);
        printf("Exec 1...\n");
        execv(pro1, p1args);
        printf("ERROR\n");
     }
     else
     {
        waitpid(pid,&st,0);
        if(st<0)
        {
           printf("Child Error\n");   
        }
        dup2(fd[0],0);
        close(fd[1]);
        close(0);
        printf("Exec...\n");
        execv(pro2,p2args);
        printf("ERROR\n");
     }
     return;
  }
  /* THIS IS JUST COMMAND LINE PARSING */
  int main(int argc, char * argv[])
  {
     int i = 1;
     char * pro1;
     char * pro2;
     char * first[argc+1];
     char * second[argc+1];
     while(i<argc && argv[i][0] != ';')
     {
        if(i == 1)
        {
           pro1 = argv[i];
        }
        else
        {
           first[i] = argv[i];
        }
        i++; 
     }
     first[i] = NULL;
     while(i<argc)
     {
        if(argv[i][0] == ';')
        {
           i++;
           pro2 = argv[i];
        }
        else
        {
           second[i] = argv[i];
        }
        i++; 
     }
     second[i] = NULL;
     pipeit(pro1,pro2,first, second);
     return 0;
  }

共有1个答案

冯鸿哲
2023-03-14

在孩子身上,你有:

    dup2(fd[1],1);
    close(fd[0]);
    close(1);

这会将管道复制到标准输出,但随后会关闭标准输出。通过不关闭标准输出并关闭管道的两端来进行修复。经验法则:如果您将管道的一端复制到标准输入、输出或错误,您应该关闭两个原始管道描述符。

    dup2(fd[1],1);
    close(fd[0]);
    close(fd[1]);

在关闭标准输入的父级中也存在类似的问题。

您还将< code>wait()放在了错误的位置。这些进程必须同时运行。如果管道中的第一个进程生成的数据太多,管道无法容纳全部数据,那么该进程将会阻塞。如果另一个进程在读取任何东西之前等待第一个进程死亡,它就不会很好地工作。

 类似资料:
  • 我有一个应用程序,可以接受一个POST请求。为了请求,我需要定义一些标题、边界和连字符。换句话说,我需要制定完整的请求。我成功地使用了HttpURLConnection。现在,我想从我的Spring应用程序中请求应用程序。 比如说,我有三个应用程序A(传感器)、B(Spring)和C(服务器)。 在这种情况下,B将充当网桥,从a接收请求,对其进行身份验证并将其发送给C。 我不想在Spring中再次

  • 问题内容: 我正在用Go编写程序,该程序执行类似程序的服务器(也就是Go)。现在,我想在启动父程序的终端窗口中获​​得子程序的标准输出。一种方法是使用函数,但这仅在进程退出后才输出标准输出。(这是一个问题,因为这个类似于服务器的程序运行了很长时间,并且我想读取日志输出) 变量是,我不知道该如何使用它来完成任务,因此我在网络上找不到有关此主题的任何有用信息。 对代码的解释:取消注释该函数以获取要编译

  • 我有两个在Tomcat7.0下运行的web应用程序 https://secure.example.com:8443 http://insecure.example.com:8080 null 是否可以用单个tomcat实例来配置它?

  • 问题内容: 我想从Groovy程序中执行foo.bat,并将生成的进程的输出重定向到stdout。Java或Groovy代码示例都可以。 foo.bat可能需要花费几分钟才能运行并生成大量输出,因此我希望在生成后立即查看输出,而不是必须等到该过程完成之后才能立即查看所有输出。 问题答案: 它使用一个类读取执行的程序生成的所有输出,并将其显示在其自己的stdout中。

  • 问题内容: 我想将子进程的stderr输出重定向到stdout。常量应该这样做,不是吗? 然而, 确实 输出了一些东西。为什么会这样,如何在stdout上得到错误消息? 问题答案: 仔细阅读源代码即可得出答案。特别是,该文档在显示以下内容时会产生误导: 表示(…)的特殊值表示标准错误应与标准输出进入同一 句柄 。 由于在求值时stdout设置为“默认”(技术上来说),因此stderr也设置为“默认

  • 我希望能够从子进程中独立读取stdout/stderr(以及我正在介绍的一个新的stdlog),对这些流做一些事情,并以相同的顺序将它们写入屏幕和日志文件。 例如,如果子进程想对stdout说“aa”,然后对stderr说“bb”,然后再对stdout说“cc”,我想在屏幕上看到“aabbcc”。如果我看到“aaccbb”,我可以容忍它(我想这是没办法的),但我肯定不想看到“aacbbc”(用一个