【问题标题】:pipe redirection issue, lost data管道重定向问题,丢失数据
【发布时间】:2021-08-28 09:14:43
【问题描述】:

我想用一个小的 c 程序重现这个 shell 行为:

< file cmd1 | cmd2

所以它需要三个参数,例如可以这样执行:

./a.out foo /bin/cat /usr/bin/wc

这是我的代码,没有错误检查:

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

static void exe_cmd(char *cmd, char **env)
{
    int     pid;
    char    *av[] = {cmd, NULL};

    pid = fork();
    if (pid == 0)
    {
        execve(av[0], av, env);
        exit(0);
    }
    waitpid(pid, NULL, 0);
}

static void left_pipe_side(int fd[2], char *cmd, char *path, char **env)
{
    int file;

    file = open(path, O_RDONLY);
    dup2(fd[1], STDOUT_FILENO); // Can be commented out to see the first command output
    dup2(file, STDIN_FILENO);
    close(fd[0]);
    close(fd[1]);
    close(file);
    exe_cmd(cmd, env);
}

static void right_pipe_side(int fd[2], char *cmd, char **env)
{
    dup2(fd[0], STDIN_FILENO);
    close(fd[1]);
    close(fd[0]);
    exe_cmd(cmd, env);
}

int main(int ac, char **av, char **env)
{
    int fd[2];
    pid_t   pid;

    pid = fork();
    pipe(fd);
    if (pid == 0)
    {
        left_pipe_side(fd, av[2], av[1], env);
        exit(0);
    }
    right_pipe_side(fd, av[3], env);
    waitpid(pid, NULL, 0);
    return (0);
}

我的问题是wc 作为第二个命令的输出总是0 0 0,就好像输入是空的(但给定的文件包含文本)。 如果我注释掉我在左侧管道中将 fd[1] 复制到 stdout 的行,第一个命令将正确输出,所以我不明白为什么重定向会使这些数据“消失”

【问题讨论】:

    标签: c unix pipe


    【解决方案1】:

    你在fork 之后打开pipe,所以每个进程都有自己的非常不相关 pipe。之前打开它,以便它在进程之间共享。

    pipe(fd);
    pid = fork();
    

    【讨论】:

      【解决方案2】:

      在您的代码中,您在fork 之后打开pipe,这意味着每个进程都有自己的pipe,这不是管道的工作方式

      您必须在 fork 之前打开 pipes,这会使进程与您的管道链接。

      #include <unistd.h>
      #include <stdlib.h>
      #include <fcntl.h>
      
      static void exe_cmd(char *cmd, char **env)
      {
          int     pid;
          char    *av[] = {cmd, NULL};
      
          pid = fork();
          if (pid == 0)
          {
              execve(av[0], av, env);
              exit(0);
          }
          waitpid(pid, NULL, 0);
      }
      
      static void left_pipe_side(int fd[2], char *cmd, char *path, char **env)
      {
          int file;
      
          file = open(path, O_RDONLY);
          dup2(fd[1], STDOUT_FILENO); // Can be commented out to see the first command output
          dup2(file, STDIN_FILENO);
          close(fd[0]);
          close(fd[1]);
          close(file);
          exe_cmd(cmd, env);
      }
      
      static void right_pipe_side(int fd[2], char *cmd, char **env)
      {
          dup2(fd[0], STDIN_FILENO);
          close(fd[1]);
          close(fd[0]);
          exe_cmd(cmd, env);
      }
      
      int main(int ac, char **av, char **env)
      {
          int fd[2];
          pid_t   pid;
          /************************ the error part **********************/
          // pid = fork();
          // pipe(fd);
          pipe(fd);
          pid = fork();
          /**************************************************************/
      
          if (pid == 0)
          {
              left_pipe_side(fd, av[2], av[1], env);
              exit(0);
          }
          right_pipe_side(fd, av[3], env);
          waitpid(pid, NULL, 0);
          return (0);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-23
        • 2011-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-06
        • 1970-01-01
        相关资源
        最近更新 更多