在 Linux 下如何强制进程刷新写入打开文件描述符的数据?

Mad*_*Ady 5 log-files realtime process max-file-descriptors

我有一个在嵌入式 Linux 系统上运行的二进制进程(没有可用的源)。该进程会打开一个日志文件 (/tmp/dmaosd.log),在其中记录其正在执行的操作。

问题是日志以块的形式更新(一次大约 1000 个字节),所以我无法使用 tail -f 实时查看日志。

我想知道是否有任何方法可以强制正在运行的进程刷新其数据(基于访问 /proc/1234/fd/3)而无需访问其源并且不向其发送任何信号(我不确定是什么信号它支持也不支持他们应该做什么)。

所讨论的过程是媒体播放器的 OSD,日志信息通常显示屏幕上选择/显示了哪些元素,因此最好尽快获得数据。

谢谢!

Luc*_*nti 8

这实际上取决于缓冲区的位置:如果应用程序使用自己的日志记录缓冲区,则无法强制刷新。

如果缓冲是由 C 库完成的,那么您可以使用 LD_PRELOAD 来禁用缓冲。假设该程序正在使用fopen()打开其日志文件,您可以执行以下操作:

#define _GNU_SOURCE 1
#include <dlfcn.h>
#include <stdio.h>

static FILE* (*libc_fopen)(char const *, char const *);

FILE * fopen(char const *name, char const *mode) {
    FILE *ret;
    if (!libc_fopen)
        libc_fopen = dlsym(RTLD_NEXT, "fopen");

    ret = libc_fopen(name, mode);
    if (!ret)
        return ret;

    setvbuf(ret, NULL, _IONBF, 0);

    return ret;
}
Run Code Online (Sandbox Code Playgroud)

编译为共享库,然后使用LD_PRELOAD“注入”到程序中:

LD_PRELOAD=./nobuffering.so myprogram
Run Code Online (Sandbox Code Playgroud)

如果您愿意,您还可以检查文件的名称并仅为您感兴趣的日志文件更改缓冲。