受您的问题启发,我编写了一个简单的程序,可以让您执行以下操作:
$ myprogram 2>&1 | ftee /tmp/mylog
它的行为类似于,
tee但将stdin克隆到stdout和命名管道(现在是必需的)而没有阻塞。这意味着,如果您想以这种方式记录日志,则可能会丢失日志数据,但是我想这在您的情况下是可以接受的。诀窍是阻止SIGPIPE信号并忽略写入损坏的fifo时的错误。当然,可以通过各种方式优化此示例,但是到目前为止,我猜它已经完成了工作。
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <signal.h>#include <unistd.h>int main(int argc, char *argv[]){ int readfd, writefd; struct stat status; char *fifonam; char buffer[BUFSIZ]; ssize_t bytes; signal(SIGPIPE, SIG_IGN); if(2!=argc) { printf("Usage:n someprog 2>&1 | %s FIFOn FIFO - path to a" " named pipe, required argumentn", argv[0]); exit(EXIT_FAILURE); } fifonam = argv[1]; readfd = open(fifonam, O_RDonLY | O_NONBLOCK); if(-1==readfd) { perror("ftee: readfd: open()"); exit(EXIT_FAILURE); } if(-1==fstat(readfd, &status)) { perror("ftee: fstat"); close(readfd); exit(EXIT_FAILURE); } if(!S_ISFIFO(status.st_mode)) { printf("ftee: %s in not a fifo!n", fifonam); close(readfd); exit(EXIT_FAILURE); } writefd = open(fifonam, O_WRonLY | O_NONBLOCK); if(-1==writefd) { perror("ftee: writefd: open()"); close(readfd); exit(EXIT_FAILURE); } close(readfd); while(1) { bytes = read(STDIN_FILENO, buffer, sizeof(buffer)); if (bytes < 0 && errno == EINTR) continue; if (bytes <= 0) break; bytes = write(STDOUT_FILENO, buffer, bytes); if(-1==bytes) perror("ftee: writing to stdout"); bytes = write(writefd, buffer, bytes); if(-1==bytes);//Ignoring the errors } close(writefd); return(0);}您可以使用以下标准命令进行编译:
$ gcc ftee.c -o ftee
您可以通过运行以下命令快速进行验证:
$ ping www.google.com | ftee /tmp/mylog
$ cat /tmp/mylog
另请注意-这不是多路复用器。一次只能执行一个进程
$ cat /tmp/mylog。



