I have a service that I want to run under systemd. It is written in perl, where by default output is line buffered if STDOUT is connected to a terminal. (Which seems similar to python)

The consequence is output arrives to journalctl -f -u my.service in chunks of many lines at a time - when the buffer runs full.

I know I can modify the service source to auto-flush STDOUT ($|=1 in perl).

I know I can also use unbuffer from expect:

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

but then I get another process involved and such a "solution" has a bad smell to me. (E.g. the "Main PID" is that of unbuffer, not of /my/program.pl). And the whole point of systemd is to avoid weird shell workarounds like this one.

So is there some way I can run such services unaltered in a way that makes them think they're connected to a terminal so they flush their STDOUT? I've looked at StandardOutput= but didn't find anything useful.


Not really, no. The buffering is set per-process via a setbuf(3) call which scripting languages offer varying degrees of control over (TCL: complete, Perl|Python|Ruby: incomplete, Shell: not at all). You would need to use a wrapper that fakes a terminal (unbuffer, expect, tmux) or to try unportable system call monkey patching (stdbuf) to try to influence how the output is done, or to add code to each application such that output can be set to be unbuffered, line buffered, or block buffered (or whatever subset of those the language offers, if any). Some applications will already have flags for this, e.g. -l of tcpdump, or it is not hard to add such code:

#!/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;

if this is saved as lflag and made executable the behavior difference can then be observed by running:

$ ./lflag | cat


$ ./lflag -l | cat
  • Not what I was hoping for, but a perfectly good answer. I'll accept it. Thanks, thrig! – Peter V. Mørch May 23 '18 at 8:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.