我正在读取另一个生成输出(缓慢且无限)的进程的输出。因为我想实时读取这些数据,所以我使用“stdbuf -oL”(行缓冲,数据是文本)。我无法控制生成过程,因此我无法修改源以强制刷新。
到目前为止 stdbuf 工作得很好,但是该进程使用 SOCK_RAW 并且需要以 root 身份运行,具有 setuid(0) 或cap_net_raw
功能。当使用 setuid 或功能以非 root 身份运行时,stdbuf 似乎被忽略了。让我演示一下这个问题:
这是一个简单的作家:
#include <stdio.h>
#include <unistd.h>
int main(){
int i;
for ( i = 0;; i++){
fprintf(stdout, "%d\n", i);
sleep(1);
}
}
和一个简单的读者:
#include <stdio.h>
int main(){
char* line = NULL;
size_t n = 0;
while (getline(&line, &n, stdin) != -1 ) {
fputs(line, stdout);
}
}
正如预期的那样,./writer | ./reader
在缓冲区填满之前,什么都不显示。前置stdbuf -oL
启用行缓冲,我将这些行输入阅读器:
% stdbuf -oL ./writer | ./reader
0
1
2
...
但是,如果我添加cap_net_raw+ep
它会停止工作:
% sudo setcap cap_net_raw+ep ./writer
% stdbuf -oL ./writer | ./reader
(no output)
使用 setuid 时观察到相同的行为:
% sudo chown root:root ./writer
% sudo chmod +s ./writer
% stdbuf -oL ./writer | ./reader
(no output)
我有兴趣了解为什么会发生这种情况以及如何在不以 root 身份运行的情况下继续使用 stdbuf。我承认我并不完全了解 setuid 在幕后所做的事情。