【问题标题】:Use of popen in pipes in c在c中的管道中使用popen
【发布时间】:2016-02-02 09:52:33
【问题描述】:

我将像 ls 这样的命令作为输入并使用 popen 执行命令并将结果存储在缓冲区中。但是,它不会打印命令的所有内容。请帮我。 PS 当整个代码都在 main 中时它能够工作。我已经尝试过 gdb 但我无法进行调试。

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



void process_command(char * command, char * buffer)
{
    int     fd[2], nbytes;
    pid_t   childpid;
    char    readbuffer[1025];
    FILE *fp = NULL;
    pipe(fd);


    if((childpid = fork()) == -1)
    {
            perror("fork");
            exit(1);
    }

    int b = 0;
    int status = 0;

    if(childpid == 0)
    {
            /* Child process closes up input side of pipe */
            close(fd[0]);
            fp = popen(command,"r");

            /* Send "string" through the output side of pipe */
          while((b = fread(readbuffer,1,1024,fp)) > 0)  
               write(fd[1], readbuffer, b);

          status = pclose(fp);

     }

    else
    {
            /* Parent process closes up output side of pipe */
            close(fd[1]);
            waitpid(childpid,&status,0);
            /* Read in a string from the pipe */
           do
          {
            nbytes = read(fd[0], buffer, sizeof(buffer));
          }while(nbytes == -1);
          buffer[nbytes] = '\0';  
    printf("Received string: %s", buffer);
    }


}


#define MAX 1024

int main(void)
{
  char command[MAX] ;
  char buffer[MAX];
  scanf("%s",command);
  process_command(command,buffer);

    return(0);
}  

【问题讨论】:

  • 为什么是孩子和父母?为什么不直接写信给buffer
  • 缓冲区写入不完整的问题。

标签: c pipe popen


【解决方案1】:

问题在于您如何读取子进程的输出。特别是这样的声明:

        nbytes = read(fd[0], buffer, sizeof(buffer));

数组buffer 是从main() 传递过来的,它被转换为函数process_command() 中的一个指针。所以sizeof(buffer) 是指针的大小,而不是数组的大小,这与sizeof(char*) 相同。假设您在一个 64 位系统上,指针大小为 8 个字节。所以你只会读取 8 个字节。

要么将数组大小作为附加参数传递,要么使用MAX

        nbytes = read(fd[0], buffer, MAX);

补充说明:

  • 您正在使用无法读取空格分隔输入的%s 读取命令。因此,如果您想运行ls /tmp,那么它将无法正常工作。考虑使用fgets()

  • 即使缓冲区大小正确,您也只能读取 1024 个字节。因此,如果子进程的输出更长,那么它将被截断。最好是read(),只要有输出并在循环打印它。

【讨论】:

    猜你喜欢
    • 2013-11-09
    • 2023-03-24
    • 2010-12-16
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多