systemd에서 실행하고 싶은 서비스가 있습니다. 이는 Perl로 작성되었으며 STDOUT
터미널에 연결되면 출력은 기본적으로 라인 버퍼링됩니다. (이건파이썬과 비슷하다)
결과적으로 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