将未命名管道输出重定向到c中的日志文件

将未命名管道输出重定向到c中的日志文件,c,pipe,fork,dup2,C,Pipe,Fork,Dup2,我想将未命名管道的输出重定向到c中打开的日志文件,但似乎无法实现,我的代码如下所示: close(fildes[1]); FILE * file = fopen(logfile, "w"); int fd = fileno(file); if (fd == -1) { bail_out(EXIT_FAILURE, strerror(errno)); } /* if (dup2(fd, fildes[0]) == -1) { bail_out(EXIT_FAILURE,

我想将未命名管道的输出重定向到c中打开的日志文件,但似乎无法实现,我的代码如下所示:

close(fildes[1]); 

FILE * file = fopen(logfile, "w");
int fd = fileno(file);

if (fd == -1) {
bail_out(EXIT_FAILURE, strerror(errno));   
}

/* if (dup2(fd, fildes[0]) == -1) {
      bail_out(EXIT_FAILURE, strerror(errno));   
   } */


/* for testing purposes */
char reading_buf[3];
while(read(fildes[0], reading_buf, 3) > 0) {
  write(fd, reading_buf, 1); 
}


(void)wait(&status);
close(fildes[0]);
break;
管道被填满了,我已经用底部的while循环测试过了。但是当我注释掉dup2调用时,没有任何内容被重定向到该文件。我想我还没有完全理解dup2和管道


另外:如果我复制管道的读取端,然后关闭原始的fildes[0],管道是否会关闭?或者仅仅是FD关闭了。也不完全应该这样做。

要将输出从管道重定向到文件,需要有人从管道的读取端读取数据,然后写入文件的文件描述符。这不能仅仅通过复制文件描述符来实现

例如,假设你有一根管子

int filedes[2];
pipe (filedes);
还有一个文件

FILE *logfile = fopen (logfile_path, "w");
int logfd = fileno (logfile);
您可以使用
cat
命令启动子进程来执行重定向

int child = fork ();
if (child == 0) {
    // close the write end of the pipe
    close (filedes[1]);
    // make STDOUT point to the log file
    dup2 (logfd, STDOUT_FILENO);
    // make STDIN point to the read end of the pipe
    dup2 (filedes[0], STDIN_FILENO);
    // launch cat
    execlp ("cat", "cat", (char*) NULL);
    // in case of error
    exit (1);
}
现在,执行cat的子级将读取写入父级管道写入端的内容,并将其写入文件

// close the read end of the pipe, it's not needed in the parent
close (filedes[0]);
// write something
const char *msg = "Hello World!\n";
write (filedes[1], msg, strlen (msg));
// close the write end of the pipe, this will make the child read EOF
close (filedes[1]);
别忘了收集僵尸

wait (&status);
然后关闭文件

fclose (logfile);

关于上一个问题,当复制文件描述符时,其中两个描述符将指向同一个底层打开的文件。因此,当其中一个被关闭时,文件保持打开状态,因为它可以通过其他描述符访问

手册页对此进行了说明:

如果fd是引用基础打开文件的最后一个文件描述符 描述(请参阅open(2)),与打开的文件关联的资源 描述被释放


write调用旁边的注释没有意义,第三个参数是要写入的字节数,而不是文件描述符rbtw,这里的管道有什么意义?你不能直接写入日志文件吗?我从某个地方复制了3-4行,忘了删除注释:),当然可以,但我想如果我可以直接将输出传输到文件,而不必进行任何显式写入,会更容易。是的,我一小时后自己发现了该手册页条目,谢谢:)太糟糕了,简单的dup2不能使用管道,已经怀疑了。