【问题标题】:simulating "ls -l | sort -r" using pipes in C [closed]使用 C 中的管道模拟“ls -l | sort -r”[关闭]
【发布时间】:2016-01-25 07:21:48
【问题描述】:

这是一个作业,所以我不会问具体的。

对于这部分作业,我需要使用管道“管道”将 sort -r 转换为 ls -l。

我知道如何执行 execl,但我无法理解使用管道将“execl 的输出”传递给另一个 execl 意味着什么。

有人可以推荐一些关于如何做到这一点的读物吗?

我尝试用谷歌搜索很多不同的东西,但我就是无法理解。

我也尝试查看管道的不同解释,但所有这些对我来说都没有意义。

如果有人可以建议任何好的阅读材料来帮助不了解管道如何工作的人(除了通过命令行使用 | 传递东西)理解管道,我将不胜感激。

提前谢谢。

【问题讨论】:

  • 我投票结束这个问题作为题外话,因为要求解决一个任务

标签: c unix pipe


【解决方案1】:

基本上,您可以看到像生产者和消费者这样的管道。 看这个简单的例子。在这段代码中,父进程在管道中写入一些字符串,子进程读取它并在输出中打印。 你想要做的是接近这个,父母期望第一个命令,孩子执行第二个。但是,您可以通过让孩子执行多个命令来使其更高级。 other example

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

    /*

 Read characters from the pipe and echo them to stdout. */

    void
    read_from_pipe (int file)
    {
      FILE *stream;
      int c;
      stream = fdopen (file, "r");
      while ((c = fgetc (stream)) != EOF)
        putchar (c);
      fclose (stream);
    }

    /* Write some random text to the pipe. */

    void
    write_to_pipe (int file)
    {
      FILE *stream;
      stream = fdopen (file, "w");
      fprintf (stream, "hello, world!\n");
      fprintf (stream, "goodbye, world!\n");
      fclose (stream);
    }

    int
    main (void)
    {
      pid_t pid;
      int mypipe[2];

      /* Create the pipe. */
      if (pipe (mypipe))
        {
          fprintf (stderr, "Pipe failed.\n");
          return EXIT_FAILURE;
        }
      /* Create the child process. */
      pid = fork ();
      if (pid == (pid_t) 0)
        {
          /* This is the child process.
             Close other end first. */
          close (mypipe[1]);
          read_from_pipe (mypipe[0]);
          return EXIT_SUCCESS;
        }
      else if (pid < (pid_t) 0)
        {
          /* The fork failed. */
          fprintf (stderr, "Fork failed.\n");
          return EXIT_FAILURE;
        }
      else
        {
          /* This is the parent process.
             Close other end first. */
          close (mypipe[0]);
          write_to_pipe (mypipe[1]);
          return EXIT_SUCCESS;
        }
    }

【讨论】:

    【解决方案2】:

    一对管道包含两端,程序写入一端的任何内容都会在另一端接收。

    你的职责是让ls -l写到一端,sort -r从另一端读。

    int p[2];
    pipe(p);
    
    if (fork() == 0) {
        // first child, run ls, so its output(fd 1) should be redirected to a pipe end
        dup2(p[0], 1);
        close(p[0]); // just for safety
        close(p[1]); // just for safety
        execvl("ls", ...);
    }
    
    if (fork() == 0) {
        // second child, run sort, so its input(fd 0) should be redirected to another pipe end
        dup2(p[1], 0);
        close(p[0]); // just for safety
        close(p[1]); // just for safety
        execvl("sort", ...);
    }
    
    close(p[0]);
    close(p[1]);
    

    【讨论】:

    • 您是否将管道的读取端映射到标准输出并将写入端映射到标准输入?在exec 操作之后,您至少应该有一个退出操作,并且可能还有一条错误消息。并且字母lvexec 操作中是互斥的。看起来您脑海中似乎有 execlp() 而不是 excevp(),但这取决于这些三点中的内容。
    • 为什么dup2之后的所有代码都在两个数组索引上调用“close”?
    • @Dmitry 因为我们不再需要它们了
    • @JonathanLeffler 这只是一个例子,你肯定需要在实际代码中进行大量错误检查
    • 我遇到了错误的文件描述符错误......仍然需要做更多的研究......
    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 2012-04-10
    • 2017-04-06
    • 2021-04-06
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多