Question: From the uptime command, I know how many days and hours the system is up and running. Is there a easy way to view the exact date and time on when the system was last rebooted? i.e Exactly from what date and time the system has been up and running?
Answer: Uptime does give this information indirectly. In the following example, it indicates that the system has been up and running for “137 days, 6 hours and 13 minutes”. But, you can’t quickly calculate the exact reboot date and time from this.
$ uptime 20:52:01 up 137 days, 6:13, 1 user, load average: 0.00, 0.00, 0.00
Instead of saying the system has been up and running for the last “137 days, 6 hours and 13 minutes”, wouldn’t be nice if it says the system has been running since “Sat May 14 20:38” (or something like that)? That is exactly what any one of the following three method does.
1. Last command
Use the ‘last reboot’ command, which will display all the previous reboot date and time for the system. This picks the information from the /var/log/wtmp file.
$ last reboot reboot system boot 2.6.32-100.28.5. Sat May 14 20:38 - 23:55 (137+06:16) reboot system boot 2.6.32-100.28.5. Sun Apr 24 21:28 - 23:37 (15+09:08) wtmp begins Thu Sun 24 17:28:47 2011
2. Who command
Use the ‘who -b’ command which displays the last system reboot date and time.
$ who -b system boot 2011-05-14 20:38
3. Use the perl code snippet
If you insist on using the uptime output to calculate the last reboot time, you can do it manually, or use the following perl code-snippet.
uptime | \ perl -ne '/.*up +(?:(\d+) days?,? +)?(\d+):(\d+),.*/; $total=((($1*24+$2)*60+$3)*60); $now=time(); $now-=$total; $now=localtime($now); print $now,"\n";'
In this example, the above code-snippet displayed the following output:
Sat May 14 20:38:39 2011
I don’t remember exactly from where I got the above perl code-snippet. But, that didn’t stop me from trying to figure out what it does. Let us take this opportunity to learn little perl. This is what the above perl code-snippet does:
- -n is perl command line option. Causes the perl program to loop over the input
- -e is perl command line option. Indicates that it is a perl one liner ( i.e perl will not expect a file name, something like “perl filename.pl”).
Following are the Regex used, and its explanations:
- .*up + – Match anything until the string “up” and one or more space, for matching the following from uptime output.
- (?:(\d+) days?,? +) – Single group
- (?:(\d+) days?,? +)? – Question mark followed by this group says that this group is optional
This part says, if there is a days part in uptime output, capture it, or ignore. The following breaks down the above group in detail.
- (?:pattern) – Non capturing parenthesis which is used to group, but don’t capture the matched to memory which is $1, $2 etc ..
- (\d+) – Match one or more digit and put it into $1 (because this is the first group)
- SPACE days? – Match the literal space followed by day or days
- ,? – comma is optional
- SPACE+ – one or more spaces
The following breaks down this pattern (\d+):(\d+),.*/
- (\d+) – Capture the hour part into $2
- : – Followed by colon
- (\d+) – Capture the minute part into $3
- , – Match comma
- .* – Match everything else
Following are the rest of the time function in the above perl code-snippet.
- $total=((($1*24+$2)*60+$3)*60) – Calculate the total amount of seconds the system is UP. i.e (((days*24+hours)*60+minutes)*60 which gives the seconds (like an epoch calculation)
- $now=time(); – Get the current time in seconds ( epoch time )
- $now-=$total; – Subtract total system running time from current time. So this is getting the exact time in second when the system was started
- $now=localtime($now); – Convert the epoch time ( time in seconds ). localtime returns given epoch time in human readable format
- print $now,”\n” – Finally, this prints the time.