POSIX Shell:使用函数输出日志并在行前添加时间戳

POSIX Shell:使用函数输出日志并在行前添加时间戳

我希望 shell 脚本能够将其所有输出记录到外部文件中stdoutstderr并将时间戳添加到每行(加上一些额外的项目),而不更改脚本的调用方式。输出重定向应该发生在脚本本身内。我也不应该单独更改脚本或管道命令中的任何现有代码。理想情况下,我只需要在脚本中添加几行。

使用这两个答案:

我已经到了可以在 Bash 上运行的地步了

#! /usr/bin/env bash

CUSTOM_PREFIX1="FancyScript"
CUSTOM_PREFIX2="SomeRunID_12-3-4.5"
LOG_FILE="/var/log/script.log"

touch $LOG_FILE
exec 1>> >(while IFS= read -r line; do printf '[%s] %s %s: %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "${CUSTOM_PREFIX1}" "${CUSTOM_PREFIX2}" "${line}"; done >> "${LOG_FILE}")
exec 2>&1

# Script continues...
d
echo "Hello"

运行上面的脚本不会产生任何输出,并产生以下日志文​​件:

# cat /var/log/script.log

[2022-02-23 03:11:45] FancyScript SomeRunID_12-3-4.5: Development/shell_log.sh: line 12: d: command not found
[2022-02-23 03:11:45] FancyScript SomeRunID_12-3-4.5: Hello

到目前为止一切顺利,但我想改变两件事。

  1. 使其在 POSIX shell ( sh) 中工作而不依赖于 Bash。常规sh不喜欢exec 1>> >(...)
  2. (while IFS= read ....)我想将其通过管道传输到脚本本身内的函数,而不是那个长子进程。就像是pipe_log() {...}

答案1

我认为logger专门为此编写:写入系统日志文件。

有关详细信息,请参阅上面该实用程序的logger(1)手册 ( man logger) 和 POSIX 规范的链接。

答案2

最多先进的Unix 工具箱中的文本处理实用程序是ex/viawkm4均来自 70 年代。它们都没有时间格式化功能(尽管使用 POSIX awk,您可以通过 获取纪元时间srand(),并且 awk 或 vi 的几种实现都具有时间格式化功能作为扩展)。

perl然而,从 80 年代中期开始,POSIX 就非常普遍了,鉴于它只有一种实现,因此 POSIX 不必参与其标准化。

因此,您始终可以将sh脚本包装在:

{

  your-script here

} 2>&1 | perl -MPOSIX -pse '
  $_ = strftime("[%Y-%m-%dT%T%z]", localtime) . " $prefix$_"
  ' -- '-|=1' "-prefix=$CUSTOM_PREFIX" >> /path/to/file.log

为每一行添加时间戳。

请注意,%z这些时间戳是明确且可后处理的。

答案3

logger上面提到的适用于较旧的系统日志记录环境。在较新的、基于 systemd 的系统上,该systemd-cat实用程序更合适:

echo 'my message' | systemd-cat -p info -t /path/to/script/executing/this

相关内容