我有一个要在 systemd 下运行的服务。它是用 perl 编写的,如果STDOUT
连接到终端,默认情况下输出是行缓冲的。(这似乎类似于 python)
结果是输出一次到达journalctl -f -u my.service
多行的块 - 当缓冲区满时。
我知道我可以将服务源修改为自动刷新STDOUT
($|=1
在 perl 中)。
我知道我也可以使用unbuffer
from expect:
-ExecStart=/my/program.pl
+ExecStart=/usr/bin/unbuffer /my/program.pl
但后来我又涉及到另一个过程,这样的“解决方案”对我来说有一种难闻的气味。(例如,“主 PID”是 的unbuffer
,而不是 的/my/program.pl
)。systemd 的全部意义在于避免像这样的奇怪的 shell 变通方法。
那么有什么方法可以让他们认为他们已连接到终端,以便他们刷新他们的服务STDOUT
?我看过StandardOutput=
但没有发现任何有用的东西。
不是真的,不。缓冲是通过
setbuf(3)
调用每个进程设置的,脚本语言提供不同程度的控制(TCL:完整,Perl|Python|Ruby:不完整,Shell:根本没有)。您将需要使用伪装终端(unbuffer、expect、tmux)的包装器或尝试不可移植的系统调用猴子补丁(stdbuf
)来尝试影响输出的完成方式,或者向每个应用程序添加代码以便输出可以是设置为无缓冲、行缓冲或块缓冲(或语言提供的任何子集,如果有的话)。一些应用程序已经有这个标志,例如-l
oftcpdump
,或者添加这样的代码并不难:如果将其保存为
lflag
可执行文件,则可以通过运行以下命令来观察行为差异:或者