简体   繁体   English

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

[英]redirect unnamed pipe output to log file in c

i want to redirect the output of an unnamed pipe to an opened log file in c but i can't seem to make it happen, my code looks like this: 我想将未命名管道的输出重定向到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;

the pipe gets filled, i've tested that with the while loop at the bottom. 管道被填充,我已经在底部的while循环中进行了测试。 but when i comment out the dup2 call nothing gets redirected to the file. 但是当我注释掉dup2调用时,没有任何内容被重定向到文件。 i think i don't fully understand dup2 and pipes. 我想我不完全了解dup2和管道。

Also: if i dup2 the reading end of the pipe and then close the original fildes[0], does the pipe get closed? 另外:如果我dup2管道的读取端,然后关闭原始fildes [0],管道是否关闭? or is it simply the FD that gets closed. 还是仅仅关闭了FD。 not entirely should about that either.. 也不完全应该如此。

To redirect output from a pipe to a file, somebody needs to read from the read end of the pipe and write to the file's file descriptor. 要将输出从管道重定向到文件,需要有人从管道的读取端读取并写入文件的文件描述符。 It can't be done merely by duping the file descriptors. 不能仅通过复制文件描述符来完成。

For instance, say you have a pipe 例如,说你有一个烟斗

int filedes[2];
pipe (filedes);

and a file 和一个文件

FILE *logfile = fopen (logfile_path, "w");
int logfd = fileno (logfile);

you could launch a child process to do the redirection using the cat command 您可以使用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);
}

Now, whatever is written to the write end of the pipe in the parent will be read by the child executing cat and written to the file. 现在,执行父级的子级将读取写入父级管道的写入端的所有内容,并将其写入文件。

// 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]);

Don't forget to collect the zombie 别忘了收集僵尸

wait (&status);

and close the file 并关闭文件

fclose (logfile);

About your last question, when a file descriptor is duped there will be two of them pointing to the same underlying open file. 关于您的最后一个问题,当复制文件描述符时,将有两个指向相同的基础打开文件。 So, when one of them is closed the file remains open for it can be accessed through other descriptor. 因此,当其中一个关闭时,文件保持打开状态,因为可以通过其他描述符访问该文件。

This is explained in the close man page: close手册页对此进行了说明:

If fd is the last file descriptor referring to the underlying open file description (see open(2)), the resources associated with the open file description are freed; 如果fd是引用基础打开文件描述的最后一个文件描述符(请参见open(2)),则释放与打开文件描述关联的资源;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM