所以我试图使用管道来捕获一个文件并将其sed到一个名为newfile.txt的文件中。目前cat命令工作,使用execvp,但是它会输出到命令显示中。然后程序进入sed命令时进入无限循环。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
char *myargv2[]={"sed", "-e" "s/color/colour/g", NULL};
char *myargv1[]={"cat", "colorfile.txt", NULL};
main()
{
int f_des[2];
int fd[2];
int pipe(int filedes[2]);
int file = open("newfile.txt",O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if (file < 0)
return 1;
// create a pipe
// Open a pipe and report error if it fails
if (pipe(f_des)==-1)
{
perror("Pipe");
exit(2);
}
//fork the process
// Use switch for fork, because parent doesn't need child's pid.
switch (fork())
{
case -1: // Error
perror("Fork");
exit(2);
case 0: // Child
printf("HERE1\n");
//child will call dup2 to hook standard output to one end of the pipe. Then, execute the cat command using execvp
dup2(fd[1], fileno(stdout));
execvp(myargv1[0], myargv1);
close(fd[1]);
close(fd[0]);
perror(myargv1[0]);
close(fd[1]);
close(fd[0]);
printf("HERE12\n");
exit(3);
default: // Parent
{
printf("HERE13\n");
//parent will call dup2 to hook standard input to the other end of the pipe. Then, execute the sed command using execvp
dup2(fd[0], fileno(stdin));
execvp(myargv2[0], myargv2);
perror(myargv2[0]);
close(fd[1]);
close(fd[0]);
printf("HERE14\n");
//parent will also call dup2 to hook standard output to the file called newfile.txt
if(dup2(file,0 < 0))
return 1;
}
exit(4);
}
return 0;
}
显然我在这里挣扎。任何人都可以指出我做错了什么和/或指出了如何做到这一点的良好信息来源?
谢谢!
答案 0 :(得分:0)
一个主要问题是,您无法决定是否使用f_des
或fd
作为管道文件描述符。你有:
int f_des[2];
int fd[2];
int pipe(int filedes[2]);
…
if (pipe(f_des) == -1)
{
perror("Pipe");
exit(2);
}
pipe()
的宣言不是一个好主意;这是系统标题的作用。但严重的问题是您在f_des
中创建了管道,然后使用fd
。
另一个问题是您没有准确地关闭管道文件描述符。你也有相当多的多余代码。此代码可以正常工作:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
static char *myargv2[]={"sed", "-e" "s/color/colour/g", NULL};
static char *myargv1[]={"cat", "colorfile.txt", NULL};
int main(void)
{
int fd[2];
int pipe(int filedes[2]);
int file = open("newfile.txt",O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if (file < 0)
return 1;
if (pipe(fd)==-1)
{
perror("Pipe");
exit(2);
}
switch (fork())
{
case -1: // Error
perror("Fork");
exit(2);
case 0: // Child
printf("HERE1\n");
dup2(fd[1], fileno(stdout));
close(fd[0]); // Important (in general)
close(fd[1]); // Important (in general)
execvp(myargv1[0], myargv1);
perror(myargv1[0]);
printf("HERE12\n");
exit(3);
default: // Parent
printf("HERE13\n");
dup2(fd[0], fileno(stdin));
close(fd[0]); // Crucial
close(fd[1]); // Important (in general)
execvp(myargv2[0], myargv2);
perror(myargv2[0]);
exit(4);
}
return 0;
}
一个简单的经验法则是:
dup()
或dup2()
管道的一端连接到标准输入或标准输出,则应关闭两个原始管道文件描述符。给定输入文件colorfile.txt
包含:
this is the color of danger
coloration is not important
end of file is.
该节目的输出是:
HERE13
HERE1
this is the colour of danger
colouration is not important
end of file is.
有趣的是,如果程序的输出通过管道传输到另一个程序,则不会打印调试信息。这是默认缓冲的结果。