关闭 systemd 单元文件中的缓冲吗?

关闭 systemd 单元文件中的缓冲吗?

当我编写单元文件时,我希望将Exec*-options( ExecStartPre=, ExecStartPost=, ExecStart=, and ExecStopPost=) 的所有输出都发送到日志。但显然输出以某种方式缓冲,因此无法确定将写入日志的内容。

在我的单位文件(ulftest.service)中我有以下部分:

...
ExecStartPre=/bin/echo 'Hello'
ExecStartPre=/usr/bin/who
ExecStart=/storage/_test/venv/bin/python /storage/_test/ulftestservice.py
...

因此,我希望有一个登录用户列表(其中有 4 个)和一个你好除了正常的“开始”、“已开始”、“停止”和“已停止”行之外,还显示在日志中。

这是不是情况确实如此。它们出现与否完全是随机的(至少对我来说)。

我编写了一个小型测试循环,每 2 秒重启一次服务:

$ for x in `seq 100`; do echo $x; sudo systemctl restart ulftest.service ; sleep 2; done

运行完之后我在日志中得到了这个:

...
2017-05-10T09:40:36+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:40:38+0000 ulf44 who[27344]: ulf      pts/0        2017-05-04 09:07 (192.168.0.180)
2017-05-10T09:40:38+0000 ulf44 who[27344]: ulf      pts/1        2017-05-04 12:36 (192.168.0.180)
2017-05-10T09:40:38+0000 ulf44 who[27344]: ulf      pts/2        2017-05-05 06:48 (192.168.0.180)
2017-05-10T09:40:38+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:40:40+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
...
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/0        2017-05-04 09:07 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/1        2017-05-04 12:36 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/2        2017-05-05 06:48 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 who[28161]: ulf      pts/3        2017-05-05 11:44 (192.168.0.180)
2017-05-10T09:42:00+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Stopping UlfTest, Administrative interface...
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Stopped UlfTest, Administrative interface.
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Starting UlfTest, Administrative interface...
2017-05-10T09:42:02+0000 ulf44 systemd[1]: Started UlfTest, Administrative interface.
...

请注意,对于 100 次重启,大多数情况下我都没有得到输出你好但是我得到了 2 轮输出who,但只有其中一轮完成。

我使用的是全新的 Ubuntu 16.04。我也在堆栈溢出

这是功能、错误还是我完全用错了方法?请指教!

答案1

man systemd.exec

我认为你需要在你的单位尝试使用StandardOutput=journal

 journal connects standard output with the journal which is accessible via journalctl(1). Note that everything that is written to syslog or kmsg (see below) is
           implicitly stored in the journal as well, the specific two options listed below are hence supersets of this one.

答案2

你可能会遇到长期存在的 systemd 错误。有关更多信息,请参阅已接受的答案: systemd 无法持续​​捕获和记录 stdout

答案3

除了刷新标准输入,您还可以使用package.iunbuffer中的命令expect

你的单元文件看起来会像这样:

... [Service] ExecStart=/usr/bin/unbuffer /path/to/your/scripts.py ...

另一个可以让您获得更多控制权的选项是使用stdbuf哪些调用,setvbuf()但这仅在您使用它运行的进程不调用 setvbuf() 本身来取消更改时才有效。

相关内容