写入stdout和文件
我有一个父进程,它要求子进程执行execv()。
我需要execv()给出的输出到stdout以显示在屏幕上,同样也复制到日志文件。
如何在不使用管道或T恤的情况下将相同的输出写入stdout和文件?
如果您不想使用tee,在编写数据之前,请将其写入文件,然后将其发送到stdout。
您应该编写一个日志function,为您执行此操作以使其更清晰。
把它穿过发球台 。
你可以使用dup2()
– 这个链接提供了一个例子
您可以在程序中完全执行此操作,但仍需要使用由pipe()
系统调用创建的匿名管道。
基本上,您将需要一个执行相当于 tee
的子tee
,这非常简单:
int child_pipe[2]; pid_t pid_exec_child, pid_output_child; pipe(child_pipe); pid_exec_child = fork(); if (pid_exec_child == 0) { dup2(child_pipe[1], STDOUT_FILENO); close(child_pipe[0]); close(child_pipe[1]); execve(/* ... */); _exit(127); } close(child_pipe[1]); pid_output_child = fork(); if (pid_output_child == 0) { /* This child just loops around, reading from the other child and writing everything * to both stdout and the log file. */ int logfd = open("logfile", O_WRONLY); char buffer[4096]; ssize_t nread; while ((nread = read(child_pipe[0], buffer, sizeof buffer) != 0) { size_t nwritten_total; ssize_t nwritten; if (nread < 0) { if (errno == EINTR) continue; perror("read"); _exit(1); } /* Copy data to stdout */ nwritten_total = 0; while (nwritten_total < nread) { nwritten = write(STDOUT_FILENO, buffer + nwritten_total, nread - nwritten_total); if (nwritten < 0) { if (errno == EINTR) continue; perror("write(stdout)"); _exit(2); } nwritten_total += nwritten; } /* Copy data to logfile */ nwritten_total = 0; while (nwritten_total < nread) { nwritten = write(logfd, buffer + nwritten_total, nread - nwritten_total); if (nwritten < 0) { if (errno == EINTR) continue; perror("write(logfile)"); _exit(3); } nwritten_total += nwritten; } } _exit(0); } close(child_pipe[0]); /* Parent continues here */
当然,在第二个孩子中执行tee
可能更容易......
(请注意,子进程使用_exit()
,因为它们从父进程inheritance了标准I / O状态)。
此外,你可以使用fifo’s。 mkfifo my.fifo; 在execv:program> my.fifo; 并打开fifo作为常规文件,从中读取。 这样您可以解析stdout,但共享访问有一些小缺点。
您是否只想将孩子的输出转到日志?
tee unix命令完全按照您的描述执行:管道输入数据并将其写入日志和标准输出。
像这样使用Tee :
./myprog | tee outputfile