c pipe ls 将字符串返回给父级

c pipe ls returned strings to parent

我目前正在尝试 运行 在我的 C 代码中使用 ls 命令,然后通过 fd 将输出的字符串通过管道传输到父进程。

我目前面临的问题是,我执行了 ls 命令,但我不知道如何存储字符串(如果有必要的话),然后将它们通过管道传输到我的父进程并执行另一个命令使用我在评论中写的给定输入。还有一种方法可以阻止 ls 输出到我的子进程中的终端吗?

int main(void)
{

   int fd1[2]; // Used to store two ends of first pipe
   int fd2[2]; // Used to store two ends of second pipe

   pid_t p;

   p = fork(); // Now forking to create a child

   // Parent process
   else if (p > 0)
   {    
      close(fd1[0]); // Close reading end of first pipe

      // Wait for child to send the strings
      wait(NULL);

      close(fd2[1]); // Close writing end of second pipe

      // Read strings from child, print it and close
      // reading end.
      read(fd2[0], "", 100);
      close(fd2[0]);
      // todo another command like "wc -l" and print the result to the terminal with write 

   }
   // Child process
   else
   {
      close(fd1[1]); // Close writing end of first pipe

      // execute ls command and send the strings to the parent
      int status;
      char *args[2];

      args[0] = "/bin/ls";        // first arg is the full path to the executable
      args[1] = NULL;             // list of args must be NULL terminated

      execv( args[0], args );     // child: call execv with the path and the args
      
      // Close both reading ends
      close(fd1[0]);
      close(fd2[0]);

      // write the strings to the parent
      write(fd2[1], "", strlen("") + 1);
      close(fd2[1]);

      exit(0);
   }

   return EXIT_SUCCESS;
}

如果这是一个愚蠢的问题,我很抱歉,但我对分叉和使用管道还很陌生。

要开始,必须在 int [2] 上调用 pipe 以创建管道。你还没有这样做。


在父进程中:

这个read调用

read(fd2[0], "", 100);

没有意义。 "" 是 read-only、char [1]。尝试在其中存储数据将调用 Undefined Behavior.

您需要一个合理大小的缓冲区(数组)来存储您读入的数据。此外,您应该通过测试 read 的 return 值来检查是否确实读取了任何数据,这是读取的字节数。

请记住,此数据不是空终止的 - 它是原始字节,而不是字符串。如果你想把它当作一个字符串,你需要手动null终止缓冲区(一定要留出空间)。


在子进程中:

要将 ls 的标准输出重定向到管道的写入端,而不是终端,使用 dup2

dup2 使由其第二个参数指定的文件描述符引用与其第一个参数相同的文件描述

execv makes little sense, as execv后面的代码如果成功了就永远不会returns。您应该在此之前关闭所有不必要的文件描述符,然后仅处理失败状态。


这一切的粗略示例。

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

int main(void) {
    int my_pipe[2];

    if (pipe(my_pipe)) {
        perror("pipe");
        return 1;
    }

    if (fork()) {
        ssize_t bytes;
        char buffer[512];

        close(my_pipe[1]);

        while ((bytes = read(my_pipe[0], buffer, sizeof buffer - 1)) > 0) {
            buffer[bytes] = 0;
            printf("Parent got:\n%s\n", buffer);
        }

        close(my_pipe[0]);

        wait(NULL);
    } else {
        char *args[] = {
            "/bin/ls",
            NULL
        };

        close(my_pipe[0]);
        dup2(my_pipe[1], fileno(stdout));
        close(my_pipe[1]);

        execv(args[0], args);

        /* we only get here if execv fails */
        perror("execv");
    }
}