如何确保在 systemd 下运行的脚本中使用“tee”时显示其输出

如何确保在 systemd 下运行的脚本中使用“tee”时显示其输出

我有一个正在运行的脚本systemd,其中有一些调试日志,我想将其发送到 stdout(最终应该出现在系统日志中,可用来查看journalctl)以及我的文件系统上的日志文件。

通常我会用来tee实现这一点(写入标准输出和文件),当我单独运行脚本时,它工作正常(我可以看到控制台和日志文件中的所有日志),但是当我在系统日志下运行它时,我丢失了系统日志中systemd的大量输出(尽管所有日志tee存在于日志文件中)。

我尝试了一些方法,但都没有解决问题:

  • stdbuf(按照建议这里用于强制行缓冲输出)在ExecStart=我的服务文件中。
  • StandardOutput=journal+console在我的服务文件中(DefaultStandardOutput未设置/etc/systemd/system.conf,因此它具有默认值journal)。
  • 删除了tee,因此echo直接写入 stdout。当我这样做时,我查看系统日志中的所有日志(但我丢失了日志文件)。我想我可以tee用一个执行两次 s 的函数来制作自己的echo日志(一次到日志文件,一次到 stdout),但这感觉有点不合时宜。我更喜欢使用tee,它已经存在用于此目的...

我在 Manjaro 和 Ubuntu 上重现了这个问题(systemd 249 (249.4-2-manjaro)systemd 245 (245.4-4ubuntu3.5)),但我不能在 Debian 11 上重现它(systemd 247 (247.3-6))。我没有看到任何配置在/etc/systemd正常工作的 Debian 系统和非正常工作的 Manjaro 系统之间有任何明显的区别。我不确定还有哪些系统配置会影响这一点……

我有完整的复现说明这里

我的脚本

住在/tmp/tee_test.sh

#!/bin/bash

LOGFILE=/tmp/testtee.log
echo > "$LOGFILE"
echo "i like pie" | tee -a "$LOGFILE"

i=2
while :; do
    echo "i shall eat $i slices of pizza" | tee -a "$LOGFILE"
    ((i++))
    sleep 1
done

我的 systemd 单元

存在于~/.config/systemd/user/tee_test.service并且systemctl --user daemon-reload每次我改变它时都会加载。

[Unit]
Description=Test teeing under systemd

[Service]
# same result with either of the following two variants
ExecStart=/tmp/tee_test.sh
# ExecStart=stdbuf -i0 -o0 -e0 /tmp/tee_test.sh

# same result with or without this guy
StandardOutput=journal+console

[Install]
WantedBy=default.target

记录系统日志

使用 查看journalctl --user -x -u tee_test.service。我只看到日志的子集。

Oct 20 09:49:03 grinchel systemd[2678]: Started Test teeing under systemd.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://forum.manjaro.org/c/support
░░
░░ A start job for unit UNIT has finished successfully.
░░
░░ The job identifier is 8193.
Oct 20 09:49:26 grinchel tee_test.sh[399363]: i shall eat 25 slices of pizza
Oct 20 09:49:40 grinchel tee_test.sh[400047]: i shall eat 39 slices of pizza
Oct 20 09:49:48 grinchel tee_test.sh[400430]: i shall eat 47 slices of pizza
Oct 20 09:49:49 grinchel tee_test.sh[400496]: i shall eat 48 slices of pizza
Oct 20 09:49:50 grinchel tee_test.sh[400529]: i shall eat 49 slices of pizza
Oct 20 09:49:51 grinchel tee_test.sh[400595]: i shall eat 50 slices of pizza
Oct 20 09:50:14 grinchel tee_test.sh[401790]: i shall eat 73 slices of pizza
Oct 20 09:50:27 grinchel systemd[2678]: Stopping Test teeing under systemd...

日志文件中的日志

在我的日志文件中我可以看到所有的日志。

i like pie
i shall eat 2 slices of pizza
i shall eat 3 slices of pizza
i shall eat 4 slices of pizza
i shall eat 5 slices of pizza
i shall eat 6 slices of pizza
i shall eat 7 slices of pizza
[...many similar lines snipped -- they ARE all present in sequence as expected...]
i shall eat 84 slices of pizza
i shall eat 85 slices of pizza
i shall eat 86 slices of pizza

知道这是怎么回事吗?如何确保所有输出都tee显示在我的系统日志中?

相关内容