代码如下。
问题 1:
如果 dup2(fd3, STDOUT_FILENO)
,string2
将在 log.txt 中。
如果 dup2(g_ctl[0], STDOUT_FILENO)
,string2
将不会被 g_ctl[1]
接收。
string1
和 ls -al
输出将被接收,为什么?
问题 2:
第三个库有一些stdout/stderr日志,如果使用dup2(socket_fd, STDOUT_FILENO)
,所有的日志都会被socket收集。但是我也想同时打印所有日志到屏幕,怎么办?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
static pthread_t g_pid;
static int g_ctl[2] = {-1, -1};
void *_run_loop(void *args) {
char buf[1024];
int n;
while (1) {
n = recv(g_ctl[1], buf, 1024, 0);
if (n > 0) {
fprintf(stderr, "%.*s\n", n, buf);
}
}
}
int main(int argc, char const *argv[])
{
int fd3 = open("./log.txt", O_CREAT | O_RDWR | O_APPEND, 0666);
int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, g_ctl);
assert(ret == 0);
ret = dup2(g_ctl[0], STDOUT_FILENO);
assert(ret > 0);
pthread_create(&g_pid, NULL, _run_loop, NULL);
send(STDOUT_FILENO, "string1", 5, 0);
system("ls -al");
printf("string2\n");
sleep(5);
return 0;
}
最佳答案
问题 1:您需要在 printf 之后 fflush(stdout);
。否则 printf 可能会缓冲您的输出。它会在您的程序退出时写入(如果尚未写入),但到那时您的阅读线程已经被取消,因此您无法阅读它。
Q2:据我所知,将输出写入两个文件的唯一方法是将其实际写入两个文件描述符。在 Unix 中没有办法“双重复制”一个文件描述符。即使像 tee
这样的命令实际上也只是为读取的每个数据 block 调用两次 write()
。您可以手动完成,也可以在函数内部或线程中完成,但您必须这样做。
关于c - 使用 dup2 重定向 printf 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55998454/