私が使用するテストスクリプトは次のとおりです。
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}'
ローカルでは、4つの日付がすべて一致します。
10個程度のサーバーで運営しています。何も報告されません(おそらく回転last reboot
によるものです)。そして一致します。しかしそれは真実ではない。正確に何が報告されますか?他のツールのレポートと一致しないのはなぜですか?wtmp
logrotate
uptime
who -b
journalctl
journalctl --list-boots
答え1
Linuxオペレーティングシステムの新しいバイナリログは、以前のバイナリログとは異なる動作をします。
以前のバイナリログ/var/log/wtmp
はとです/var/log/btmp
。システムが起動するとユーザwtmp
名でエントリが記録され、システムがシャットダウンするとユーザ名reboot
でエントリが記録されます。システムがいつ再起動したかを確認するには、コマンドを使用して項目を印刷します。wtmp
shutdown
last reboot
last shutdown
新しいバイナリログはシステムログであり、対応するエントリはありません。
代わりに、日記帳ごとというプログラムがあります。スタート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