Systemd

systemd.service:使用 pty 強制刷新標準輸出?

  • May 23, 2018

我有一個要在 systemd 下執行的服務。它是用 perl 編寫的,如果STDOUT連接到終端,預設情況下輸出是行緩衝的。(這似乎類似於 python

結果是輸出一次到達journalctl -f -u my.service多行的塊 - 當緩衝區滿時。

我知道我可以將服務源修改為自動刷新STDOUT$|=1在 perl 中)。

我知道我也可以使用unbufferfrom 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)來嘗試影響輸出的完成方式,或者向每個應用程序添加程式碼以便輸出可以是設置為無緩衝、行緩衝或塊緩衝(或語言提供的任何子集,如果有的話)。一些應用程序已經有這個標誌,例如-lof tcpdump,或者添加這樣的程式碼並不難:

#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long qw(GetOptions);

GetOptions( 'l' => \my $Flag_Unbuffer ) or exit 64;

STDOUT->autoflush(1) if $Flag_Unbuffer;

print "hi\n" for 1..4;
sleep 10;

如果將其保存為lflag執行檔,則可以通過執行以下命令來觀察行為差異:

$ ./lflag | cat

或者

$ ./lflag -l | cat

引用自:https://unix.stackexchange.com/questions/445101