systemd.service:ptyを使用して標準出力を強制的にフラッシュしますか?

systemd.service:ptyを使用して標準出力を強制的にフラッシュしますか?

systemdで実行したいサービスがあります。これはPerlで書かれており、STDOUT端末に接続すると、出力はデフォルトでラインバッファリングされます。 (これはPythonに似ています)

その結果、journalctl -f -u my.serviceバッファがいっぱいになると、出力は一度に複数行ずつ到着します。

私はサービスソースを自動更新STDOUT$|=1Perlで)に変更できることを知っています。

私も使用できることを知っていますunbuffer期待から:

-ExecStart=/my/program.pl
+ExecStart=/usr/bin/unbuffer /my/program.pl

しかし、私は別のプロセスに参加し、そのような「解決策」は私に悪い好みを与えます。 (例:「デフォルトPID」ははいunbuffer、そうではありません/my/program.pl)systemdのポイントは、このような奇妙なシェル回避策を避けることです。

それでは、これらのサービスを変更せずに実行し、端末に接続していると思うようにしてサービスを更新する方法はありますかSTDOUT?私は見たことがないStandardOutput=しかし、役に立つものが見つかりませんでした。

答え1

正確ではありません。バッファリングはsetbuf(3)呼び出しによってプロセスごとに設定され、スクリプト言語はさまざまなレベルの制御を提供します(TCL:フル、Perl | Python | Ruby:不完全、Shell:まったくありません)。ターミナルを偽造するラッパー(unbuffer、expect、tmux)を使用するか、移植不能なシステムコールサルパッチ(stdbuf)を試して、出力の実行方法に影響を与えるか、出力が可能になるように各アプリケーションにコードを追加する必要があります。 unbuffered、ラインバッファリング、またはブロックバッファリング(または言語によって提供されるサブセット(存在する場合))に設定します。一部のアプリケーションには既に-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

関連情報