我正在家里运行一个小型 Linux 服务器,我正在编写一个脚本来每 5 秒记录一次 CPU 核心的温度,但我需要时间戳才能发挥作用。到目前为止,我有一些可以保存输出的东西sensors
命令的输出保存到文件中,并且我有一个可以打印日期和时间的命令。我只需要弄清楚如何将这两者结合起来。
sensors | grep ^Core* >> temps.log
以以下格式将临时值保存在 temps.log 中:
Core 0: +39.0°C (high = +76.0°C, crit = +100.0°C)
Core 1: +40.0°C (high = +76.0°C, crit = +100.0°C)
date +%m/%d/%y-%H:%M:%S
以及我能做的返回日期
mm/dd/yy-hh:mm:ss
我用谷歌搜索了一下,看到有人建议使用,gawk
但我完全不知道如何gawk
工作。
答案1
一个脚本来记录 [...] 每 5 秒 [...] 我需要时间戳 [...] 一个循环 [...] 文件达到一定大小
您需要一个工具,它将主程序的日志输出作为输入,并将其写入有大小限制的日志文件,并添加时间戳。现有的工具可以做到这一点以及更多。他们所做的“更多”是日志文件的自动轮换,该日志文件也可以按需触发,从而维持大小上限日志目录当前和旧的日志文件。
您可以选择以下工具:
- 丹·伯恩斯坦的
multilog
来自守护进程工具 - 布鲁斯·冈特的
multilog
来自 daemontools-encore - 洛朗·贝尔科特
s6-log
从s6开始 - 格里特·佩普的
svlogd
来自鲁尼特 - 韦恩·马歇尔的
tinylog
来自罪犯 - 我的
cyclog
从小吃
假设一个长时间运行的实用程序每隔几秒打印一次所需的日志输出,如下所示:
#!/bin/sh # 监控传感器 执行2>&1 虽然是真的 做 传感器 睡5 完成 | grep --line-buffered -- '^Core'
用法很简单:
monitor-sensors | cyclog ./temps
monitor-sensors | multilog t ./temps
并且可以轻松调整:
monitor-sensors | cyclog --max-file-size 32768 --max-total-size 1048576 ./temps
monitor-sensors | s6-log t s32768 S1048576 ./temps
monitor-sensors | multilog t s32768 n5 ./temps
从这里开始,使用 daemontools-encore/runit/perp/s6/nosh 等工具集,只需一小步即可将该管道的左侧和右侧移动到run
程序中并将其作为一对链接的实际守护进程运行。
但是,如果您只想(例如)从命令行执行一次性调用,那么它们也都可以处理一次性输出到现有日志目录的情况。
其中一些工具可以执行其他形式的时间戳,但它们都可以执行 TAI64N 时间戳。 TAI64N 时间戳被设计为能够达到纳秒精度,尽管上述一些方法并没有完全实现这一点;只要你的 TZ 数据库知道它们,就可以很好地处理诸如闰秒之类的事情;和 都是微不足道的sort
,甚至是sort -m
.
TZ
使用以下工具从 TAI64N 时间戳转换为当前时区的本地时间(或者,考虑到它只是环境变量,您选择的任意时区):
- 丹·伯恩斯坦的
tai64nlocal
来自守护进程工具 - 布鲁斯·冈特的
tai64nlocal
来自 daemontools-encore - 我的
tai64nlocal
从小吃
观察这样的日志,因为它们是用以下内容编写的:
tail -F
,尽管tail
当旋转速度非常快时存在已知问题。 (这是tail
.logrotate
文件一旦完全写入,就不会出现此类额外tail
问题的风险。)- 我的
follow-log-directories
来自 nosh,它“知道”这种日志目录,并使用“光标”(永久保存在光盘上)来可靠地跟踪日志目录中的位置,以便在日志跟踪器不注意时发生多次轮换的情况下继续进行。
其他类型的处理可以使用以下工具完成:
- 拉斯·奥尔伯里
multilog-watch
logrange
- 保罗·克莱默的
multilog-stamptail
- 我的
export-to-rsyslog
从小吃
进一步阅读
- 乔纳森·德博因·波拉德 (2015)。 ”记录”。守护进程工具家族。经常给出的答案。
- 布莱恩·坎特里尔 (2013)。 游轮之旅如何成为一次奥德赛。 OmniIT Surge 2013。YouTube。
- 布莱恩·坎特里尔 (2012-07-29)。tail -f wrt 截断的行为 illumos-开发者。
- https://unix.stackexchange.com/a/294206/5132
答案2
@JdeBP 已经回答了你可能应该做什么。但这不是你提出的问题。因此,对于从 Google 到达这里并试图了解如何将内容附加/添加到多行输出的任何人来说,这里是:
首先,^Core*
它可能不会做你认为它会做的事情。它是一个正则表达式,用于匹配以“Cor”开头、紧接着任意数量的“e”的行:“Cor”、“Core”、“Coreeeee”等。
其次,xargs
它是一个很棒的工具,特别是对于单行和快速脚本来说。您可能必须xargs
对每一行输入进行操作,并使用参数为每一行发出命令-I
。所以你可以轻松地做这样的事情:
sensors | grep '^Core*' | xargs -I{} echo "${stamp}: {}" >> temps.log
加上'^Core*'
引号是因为您不希望出现意外(尽管极不可能)的 shell 扩展。 in告诉{}
用它将要执行的命令的参数中的每一行输入进行替换。当然,你也可以选择其他图案;我只是喜欢模仿 的语法。假设您将日期/时间保存在.-I
xargs
{}
find -exec
${stamp}
stamp
您还可以启动一个子 shell,date
在其中运行命令(指定您想要的任何格式),并使用xargs
其标准输出作为参数的一部分echo
:
sensors | grep '^Core*' | xargs -I{} echo "$(date): {}" >> temps.log
再说一遍,你应该做什么大概要做的是使用经过测试和维护的工具进行日志记录。但我在这里回答如何在 grep 输出中附加/添加时间戳,而不是如何正确制作日志。
答案3
如果我理解正确的话,您想要完成的是将当前日期添加到 grep 输出的每一行之前。对于 bash 脚本来说这是一个简单的任务:
sensors | grep ^Core |\
(
DATE=$(date +%m/%d/%y-%H:%M:%S)
while read LINE
do
echo "$DATE $LINE"
done
) >> temps.log
答案4
sensors | grep ^Core* | xargs -d '\n' -I%% sh -c 'echo $(date +%H:%M:%S) $0' %% > temps.log