如果您无权访问stdbuf
,则不妨模拟它并手动取消缓冲stdout
gdb
(假设显然您可以访问gdb
)。
让我们来看看stdbuf
实际是如何操作的。stdbuf
GNU coreutils 命令基本上只通过设置环境变量注入用户程序libstdbuf
。LD_PRELOAD
(无关紧要,但为了记录,选项是通过_STDBUF_E
// env vars 传递的。_STDBUF_I
)_STDBUF_O
然后,当libstdbuf
运行时,它以适当的模式(完全缓冲、行缓冲或无缓冲)在适当的文件描述符 ( / / ) 上调用setvbuf
libc 函数(依次执行底层系统调用)。stdin
stdout
stderr
声明为setvbuf
in stdio.h
,可用于man 3 setvbuf
:
#include <stdio.h>
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
的值为mode
:_IONBF
, _IOLBF
, _IOFBF
, 中定义stdio.h
。我们在这里只对无缓冲模式感兴趣:_IONBF
. 它的值为2
(您可以检查您的/usr/include/stdio.h
)。
取消缓冲脚本
所以,要为某个进程取消缓冲stdout
,我们只需要调用:
setvbuf(stdout, NULL, _IONBF, 0)
我们可以很容易地做到这一点gdb
。让我们编写一个可以调用的脚本unbuffer-stdout.sh
:
#!/bin/bash
# usage: unbuffer-stdout.sh PID
gdb --pid "$1" -ex "call setvbuf(stdout, 0, 2, 0)" --batch
然后,我们可以这样称呼它:
$ ./unbuffer-stdout.sh "$(pgrep -f my-program-name)"
(您可能需要sudo
将其运行为root
.)
测试
我们可以使用这个带有缓冲标准输出的简单 Python 程序(如果不使用-u
, 和 unset调用PYTHONUNBUFFERED
)writer.py
,:
#!/usr/bin/python
import sys, time
while True:
sys.stdout.write("output")
time.sleep(0.5)
运行它:
$ ./writer.py >/tmp/output &
$ tailf /tmp/output
并观察在我们运行之前没有输出出现:
$ sudo ./unbuffer-stdout.sh "$(pgrep -f writer.py)"