有没有简单的方法可以计算不包括系统暂停时间的正常运行时间?我想计算我在电脑前花费的时间。
答案1
一方面,这个答案晚了六年,另一方面,如果互联网是永恒的,那么这只不过是一眨眼的事!
你可以使用这个小 bash 脚本来获取真正的正常运行时间:
$ suspendtime
Apr 07 05:53:34 to Apr 07 17:07:17 suspended 11 hours, 13 minutes, 43 seconds
Apr 07 21:56:34 to Apr 08 04:20:57 suspended 6 hours, 24 minutes, 23 seconds
(... SNIP ...)
May 08 05:55:20 to May 08 16:32:37 suspended 10 hours, 37 minutes, 17 seconds
May 08 23:21:00 to May 09 07:02:05 suspended 7 hours, 41 minutes, 5 seconds
Linux uptime 2,813,939 seconds (4 weeks, 4 days, 13 hours, 38 minutes, 59 seconds)
64 Suspends 1,715,196 seconds (2 weeks, 5 days, 20 hours, 26 minutes, 36 seconds)
Real uptime 1,098,743 seconds (1 week, 5 days, 17 hours, 12 minutes, 23 seconds)
Linux 将报告正常运行时间为 8 天 40 分钟。实际正常运行时间(减去挂起时间后)约为 2 天 18 小时。
suspendtime
bash 脚本
以下是您可以复制到系统的代码:
#!/bin/bash
# NAME: suspendtime
# PATH: $HOME/askubuntu/
# DESC: For: https://askubuntu.com/questions/321855/how-to-get-real-uptime
# DATE: November 6, 2019.
# NOTE: Calculate suspend time from systemd's journalctl
# UPDT: 2019-11-07 Fine-tune removing 0 Units in DaysMinutesStr
# 2020-05-09 Add "weeks" unit measure to DaysMinutes() function
# Duplicate DaysMinutes from ~/.bashrc for Ask Ubuntu
DaysMinutes () {
local w d h m s
(( w = ${1} / 604800 ))
(( d = ${1}%604800 / 86400 ))
(( h = (${1}%86400) / 3600 ))
(( m = (${1}%3600) / 60 ))
(( s = ${1}%60 ))
DaysMinutesStr="$w weeks, $d days, $h hours, $m minutes, $s seconds"
# Convert 1's to singular
[[ ${DaysMinutesStr:0:2} = "1 " ]] && \
DaysMinutesStr="${DaysMinutesStr/weeks/week}"
DaysMinutesStr="${DaysMinutesStr/ 1 days/ 1 day}"
DaysMinutesStr="${DaysMinutesStr/ 1 hours/ 1 hour}"
DaysMinutesStr="${DaysMinutesStr/ 1 minutes/ 1 minute}"
DaysMinutesStr="${DaysMinutesStr/ 1 seconds/ 1 second}"
# Suppress zero strings
[[ ${DaysMinutesStr:0:1} = "0" ]] &&
DaysMinutesStr="${DaysMinutesStr/0 weeks, / }"
DaysMinutesStr="${DaysMinutesStr/ 0 days, / }"
DaysMinutesStr="${DaysMinutesStr/ 0 hours, / }"
DaysMinutesStr="${DaysMinutesStr/ 0 minutes, / }"
DaysMinutesStr="${DaysMinutesStr/, 0 seconds/}"
} # DaysMinutes
# Build array of suspend cycles from Systemd
IFS=$'\n' Arr=( $(journalctl -b-0 | \
grep -E 'systemd\[1]: Start.*Suspend' | cut -c1-15) )
[[ ${#Arr[@]} -gt 0 ]] && upper=$(( ${#Arr[@]} - 1 ))
[[ $upper -gt 0 ]] && for (( i=0; i<upper; i=i+2 )) ; do
(( SuspendCount++ ))
Time=$(( $(date +%s -d "${Arr[i+1]}") - $(date +%s -d "${Arr[i]}") ))
SuspendTime=$(( SuspendTime + Time ))
DaysMinutes "$Time"
printf "%s to %s suspended%s\n" "${Arr[i]}" "${Arr[i+1]}" \
"$DaysMinutesStr"
done
echo
LinuxTime=$(( $(date +%s -d "Now") - $(date +%s -d "$(uptime -s)") ))
DaysMinutes "$LinuxTime"
printf "Linux uptime %'d seconds (%s)\n" "$LinuxTime" "$DaysMinutesStr"
DaysMinutes "$SuspendTime"
printf "%s Suspends %'d seconds (%s)\n" \
"$SuspendCount" "$SuspendTime" "$DaysMinutesStr"
RealTime=$(( LinuxTime - SuspendTime ))
DaysMinutes "$RealTime"
printf "Real uptime %'d seconds (%s)\n" "$RealTime" "$DaysMinutesStr"
大约一半的程序将秒转换为人性化格式的周、日、时、分和秒。该函数DaysMinutes
执行此操作,是从我的文件中复制而来~/.bashrc
,您可能希望自己将该函数放在其中。
怎么运行的
关键部分是从以下位置获取暂停开始和结束时间journalctl
:
$ journalctl -b-0 | grep -E 'systemd\[1]: Start.*Suspend'
Oct 31 05:55:19 alien systemd[1]: Starting Suspend...
Oct 31 16:54:26 alien systemd[1]: Started Suspend.
(... SNIP ...)
Nov 07 21:07:28 alien systemd[1]: Starting Suspend...
Nov 08 05:08:52 alien systemd[1]: Started Suspend.
- 该命令读取当前启动的所有系统消息。您可以使用等
journalctl -b-0
命令增强查看上一次启动的功能-b-1
。-b-2
- 带有正则表达式的命令
grep
执行了繁重的工作,从记录的 19,330 条系统消息中返回了 32 条与暂停有关的系统消息(在我的系统上)
答案2
多年后,上述脚本需要更新。systemd 消息和 date 命令不再兼容 - 如上部脚本的注释中所述。所以我以那个为基础并进行了修改。日志返回日期为“Mai 03 ...”,无法通过日期处理。为了解决这个问题,我伪造了年份和月份 - 因此如果在待机期间更改月份,它将无法正确计算......也许有人会改变这一点。
#!/bin/bash
# NAME: suspendtime
# PATH: $HOME/askubuntu/
# DESC: For: https://askubuntu.com/questions/321855/how-to-get-real-uptime
# DATE: November 6, 2019.
# NOTE: Calculate suspend time from systemd's journalctl
# UPDT: 2019-11-07 Fine-tune removing 0 Units in DaysMinutesStr
# UPDT: 2020-05-05 works with Ubuntu 20.04 but has problem with changing monthes
# Duplicate DaysMinutes from ~/.bashrc for Ask Ubuntu
DaysMinutes () {
local d h m s
(( d = ${1} / 86400 ))
(( h = (${1}%86400) / 3600 ))
(( m = (${1}%3600) / 60 ))
(( s = ${1}%60 ))
DaysMinutesStr="$d days, $h hours, $m minutes, $s seconds"
# Convert 1's to singular
[[ ${DaysMinutesStr:0:2} = "1 " ]] && \
DaysMinutesStr="${DaysMinutesStr/days/day}"
DaysMinutesStr="${DaysMinutesStr/ 1 hours/ 1 hour}"
DaysMinutesStr="${DaysMinutesStr/ 1 minutes/ 1 minute}"
DaysMinutesStr="${DaysMinutesStr/ 1 seconds/ 1 second}"
# Suppress zero strings
[[ ${DaysMinutesStr:0:1} = "0" ]] &&
DaysMinutesStr="${DaysMinutesStr/0 days, / }"
DaysMinutesStr="${DaysMinutesStr/ 0 hours, / }"
DaysMinutesStr="${DaysMinutesStr/ 0 minutes, / }"
DaysMinutesStr="${DaysMinutesStr/, 0 seconds/}"
} # DaysMinutes
# Build array of suspend cycles from Systemd
IFS=$'\n' Arr=( $(journalctl -b-0 | grep -E 'PM: suspend' | cut -c5-15) )
[[ ${#Arr[@]} -gt 0 ]] && upper=$(( ${#Arr[@]} - 1 ))
SuspentCount=0
[[ $upper -gt 0 ]] && for (( i=0; i<upper; i=i+2 )) ; do
(( SuspendCount++ ))
Time=$(( $(date +%s -d "2020-01-${Arr[i+1]}") - $(date +%s -d "2020-01-${Arr[i]}") ))
SuspendTime=$(( SuspendTime + Time ))
printf "%s to %s lasting %'d seconds\n" "${Arr[i]}" "${Arr[i+1]}" "$Time"
done
echo
LinuxTime=$(( $(date +%s -d "Now") - $(date +%s -d "$(uptime -s)") ))
DaysMinutes "$LinuxTime"
printf "Linux uptime \t%'d seconds (%s)\n" "$LinuxTime" "$DaysMinutesStr"
if [ $SuspendCount > 0 ]; then
DaysMinutes "$SuspendTime"
printf "%sx Suspend \t%'d seconds (%s)\n" "$SuspendCount" "$SuspendTime" "$DaysMinutesStr"
fi
RealTime=$(( LinuxTime - SuspendTime ))
DaysMinutes "$RealTime"
printf "Real uptime \t%'d seconds (%s)\n" "$RealTime" "$DaysMinutesStr"