On Linux, all three commands use different sources of information by default.
uptime
uses the information given by the kernel in /proc/uptime
. The latter contains two pieces of information: the system’s uptime, including time spent suspended, and the time spent in the idle process. These values are accurate.
who -b
uses the information stored in /var/run/utmp
. On current systems, this is really /run/utmp
, and only has information for the current boot (/run
is a tmpfs
which loses its contents when the system is rebooted); but for the current boot, it is also accurate.
last reboot
uses the information stored in /var/log/wtmp
. The information stored there is also generally accurate, but the information you need might no longer be stored there: wtmp
is rotated in many setups, typically monthly. This means that if the system’s current boot time is older than wtmp
’s last rotation time, the information presented will be partial. In particular, last reboot
ends up showing the last rotation time, not the system’s actual boot time. This is why last
shows the time at which wtmp
begins: that’s the time horizon for the information displayed by last
.
When wtmp
contains the last boot time, last reboot
does show it:
$ last reboot | head -n 1
reboot system boot 5.10.0-8-amd64 Mon Sep 13 15:56 still running
$ who -b
system boot 2021-09-13 15:56
$ uptime
09:11:03 up 31 days, 17:15, 13 users, load average: 0.48, 0.34, 0.42