有没有办法从脚本中将所有 stdout 和 stderr 重定向到 systemd 日志?

Is there a way to redirect all stdout and stderr to systemd journal from within script?

我喜欢使用 systemd 的日志来查看和管理我自己的脚本的日志的想法。我已经意识到您可以根据每条消息从我的用户脚本登录到日志..

echo 'hello' | systemd-cat -t myscript -p emerg

有没有办法将所有消息重定向到 journald,即使是那些由其他命令生成的消息?喜欢..

exec &> systemd-cat

更新:

部分成功。 尝试了 Inian 来自终端的建议。

~/scripts/myscript.sh 2>&1 | systemd-cat -t myscript.sh

它起作用了,stdout 和 stderr 被定向到 systemd 的日志。 奇怪的是,

~/scripts/myscript.sh &> | systemd-cat -t myscript.sh

在我的 Bash 终端上不工作。

当其他程序调用我的脚本时,我仍然需要找到一种在我的脚本中执行此操作的方法。

我试过了..

exec 2>&1 | systemd-cat -t myscript.sh

但它不起作用。

更新 2:

来自终端

systemd-cat ~/scripts/myscript.sh

有效。但我仍在寻找一种从脚本中执行此操作的方法。

显然,出于我无法理解的原因,您无法真正从脚本中将所有 stdout 和 stderr 重定向到 journald,因为它必须通过管道输入。为了解决这个问题,我发现了人们使用的一个技巧使用 syslog 的记录器,其工作方式类似。

您可以将所有代码包装到一个函数中,然后将该函数通过管道传输到 systemd-cat。

#!/bin/bash

mycode(){
  echo "hello world"
  echor "echo typo producing error"
}
mycode | systemd-cat -t myscript.sh

exit 0

然后搜索日记日志..

journalctl -t myscript.sh --since yesterday

我很失望没有更直接的方法来做到这一点。

通往 systemd-cat 的管道是一个需要与您的脚本同时 运行 的进程。 Bash 为此提供了一个工具,尽管它不能移植到 POSIX sh

exec > >(systemd-cat -t myscript -p emerg) 2>&1

>(command) 进程替换会启动另一个进程和 returns 一个伪文件名(类似于 /dev/fd/63),您可以将其重定向到其中。如果您想将其移植到 POSIX sh.

,这基本上是 mkfifo 黑客攻击的包装器

如果您的脚本恰好不是 shell 脚本,而是其他一些允许加载链接到 -lsystemd 的扩展模块的编程语言,还有另一种方法。有一个库函数 sd_journal_stream_fd 非常精确地匹配手头的任务。从 bash 本身调用它(而不是某些 child)似乎很难。例如,在 Python 中,它可作为 systemd.journal.stream 使用。这个函数的作用本质上是连接一个 unix 域流套接字并传达正在传输的数据类型(例如优先级)。这里使用 shell 的困难部分是让它连接一个 unix 域套接字(而不是连接 child)。

这个答案的关键思想是由 Freenode/libera.chat 用户 grawity 给出的。