在c中的管道中使用popen
Use of popen in pipes in c
我将 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] = '[=10=]';
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);
}
问题在于您如何读取子进程的输出。特别是,这个声明:
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);
补充说明:
您正在使用无法读取 space 分隔输入的 %s
读取命令。所以如果你想 运行 ls /tmp
那么它是行不通的。考虑使用 fgets()
.
即使缓冲区大小正确,您也只能读取 1024 字节。因此,如果子进程的输出更长,那么它将被 t运行 处理。更好的方法是 read()
只要有输出并在 内部 循环中打印它。
我将 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] = '[=10=]';
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);
}
问题在于您如何读取子进程的输出。特别是,这个声明:
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);
补充说明:
您正在使用无法读取 space 分隔输入的
%s
读取命令。所以如果你想 运行ls /tmp
那么它是行不通的。考虑使用fgets()
.即使缓冲区大小正确,您也只能读取 1024 字节。因此,如果子进程的输出更长,那么它将被 t运行 处理。更好的方法是
read()
只要有输出并在 内部 循环中打印它。