进一步阅读

进一步阅读

这是我使用的测试脚本:

last_reboot=$(last reboot | grep 'still running' | awk '{for (i=5; i<=NF; i++) printf $i FS}' | awk '{for (i=1; i<=NF - 2; i++) printf $i FS}')
if [ "$last_reboot" ]; then
    date -d "$last_reboot" '+last reboot: %Y-%m-%d'
fi

days=$(uptime | awk '{print $3}')
hours=$(uptime | awk '{print $5}' | sed -E 's/,$//')
h=$(echo "$hours" | cut -d: -f 1)
m=$(echo "$hours" | cut -d: -f 2)
date -d "- $days days - $h hours - $m minutes" '+uptime: %Y-%m-%d'

who -b | awk '{print "who: " $3}'

journalctl --list-boots | awk '$1 == "0" {print "journalctl: " $4}'

在本地,所有四个日期都匹配。

我在大约 10 台服务器上运行它。last reboot不报告任何内容(可能是因为wtmp旋转了logrotate)。uptimewho -b匹配。但journalctl事实并非如此。具体报告什么journalctl --list-boots?为什么它与其他工具的报告不匹配?

答案1

Linux 操作系统上的新二进制日志与旧二进制日志的工作方式不同。

旧的二进制日志是/var/log/wtmp/var/log/btmp。在系统引导时,将wtmp使用用户名写入一个条目,而在系统关闭时,将使用用户名reboot写入一个条目。查找系统重新启动的时间只需使用和命令打印出这些条目即可。wtmpshutdownlast rebootlast shutdown

新的二进制日志是 systemd 日志,它们没有这样的条目。

反而,每一篇日记记录有一个名为启动ID。您可以通过选项看到这-o verbose一点journalctl。引导 ID 由内核在引导时生成,并systemd-journald在将其添加到日志时将从内核获取的当前引导 ID 应用于每个日志记录。

要实现该list-boots功能,journalctl请扫描整个期刊,读取时间戳和启动ID每条记录,并注意到最早和最晚的时间戳与每个唯一的启动 ID 相关联。

因此,如果日志的某些部分被清除,或者相反地停留时间过长,则报告的明显启动和关闭时间journalctl将与实际启动和关闭时间有很大差异。

/run/utmp是一个终端登录记录表,其中包含启动和关闭的特殊条目。这些条目由uptime和读取who -b。它们是由systemd-update-utmp类似于 FreeBSD 命令的等程序编写的utx,这些程序作为启动和关闭过程的一部分运行。它们不是最先或最后运行的,因为相关服务不是(而且实际上不能)绝对最先或最后订购的。可能存在具有相关引导 ID 的日志条目早于运行时间,以及类似的日志条目晚于运行systemd-update-utmp reboot时间。systemd-update-utmp shutdown

进一步阅读

相关内容