systemdで実行したいサービスがあります。これはPerlで書かれており、STDOUT
端末に接続すると、出力はデフォルトでラインバッファリングされます。 (これはPythonに似ています)
その結果、journalctl -f -u my.service
バッファがいっぱいになると、出力は一度に複数行ずつ到着します。
私はサービスソースを自動更新STDOUT
($|=1
Perlで)に変更できることを知っています。
私も使用できることを知っています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、ラインバッファリング、またはブロックバッファリング(または言語によって提供されるサブセット(存在する場合))に設定します。一部のアプリケーションには既に-l
of などの対応するフラグがあるか、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