我想知道 2016 年我在笔记本电脑上工作的总时间。
last reboot --since 2016-01-01 --until 2016-12-31 | grep -o '(.*)' | grep -v '-'
以这种格式给我笔记本电脑的总正常运行时间:
(01:33)
(04:40)
(01:31)
(1+06:41)
(02:47)
(00:30)
现在我该如何将其添加?
答案1
尝试使用 bash 脚本并扩展您的命令。我用它dateutils
来增加时间长度。
因此,要使用这个脚本,需要dateutils
通过 获得包apt
。( sudo apt install dateutils
)
此脚本还考虑了当前正常运行时间(当前会话),因此更加准确。不计算秒数。报告的最低单位是分钟。
#!/bin/bash
# Total uptime reported.
temp=$(last reboot --since 2016-01-01 --until 2016-12-31 | grep -o '(.*)' | grep -v '-' | sed 's/(\([0-9]\{1,\}\)+\([0-9]\{1,\}\):\([0-9]\{1,\}\))/\1d\2h\3m/g ;s/(\([0-9]\{1,\}\):\([0-9]\{1,\}\))/\1h\2m/g' )
curr=$( cat /proc/uptime | perl -ne '/(\d*)/ ; printf "%02d:%02d:%02d\n",int($1/86400),int(($1%86400)/3600),int(($1%3600)/60)' )
echo "Total run time (days:hours:minutes)"
curr="2015-01-01T"$curr
org="2015-01-01T00:00:00"
new=$(dateutils.dadd $curr $temp )
dateutils.ddiff $org $new -f "%dd %Hh %Mm"
- 首先列出自上次重启以来的正常运行时间,并对其进行格式化以提取日、时、分、秒信息。然后将其保存在 中
temp
。 - 设置了一个名为 org= 的参考虚假日期,
2015-01-01
其中添加了当前正常运行时间。 - 然后将所有累计正常运行时间添加到变量中
new
- 通过差异可以发现
org
和网络正常运行时间之间的持续时间。new
输出:
vayu@helix:$ ./uptime_record.sh
Total run time (days:hours:minutes)
57d 20h 36m
以下脚本适用于正常运行时间剧本上演之日起一年。
#!/bin/bash
# Total uptime reported since exactly 1 year (from the time script is run).
now="$(date +'%Y-%m-%d')" ;
last_y=$(dateutils.dadd $now -1y)
temp=$(last reboot --since "$last_y" --until "$now" | grep -o '(.*)' | grep -v '-' | sed 's/(\([0-9]\{1,\}\)+\([0-9]\{1,\}\):\([0-9]\{1,\}\))/\1d\2h\3m/g ;s/(\([0-9]\{1,\}\):\([0-9]\{1,\}\))/\1h\2m/g' )
curr=$( cat /proc/uptime | perl -ne '/(\d*)/ ; printf "%02d:%02d:%02d\n",int($1/86400),int(($1%86400)/3600),int(($1%3600)/60)' )
echo "Total run time in one year (days:hours:minutes)"
curr="1980-01-01T"$curr
org="1980-01-01T00:00:00"
new=$(dateutils.dadd $curr $temp )
dateutils.ddiff $org $new -f "%dd %Hh %Mm"
答案2
下面是我想要的 python 实现,但我确信有一种优雅的方法可以用 bash 来实现:
import subprocess
output = subprocess.run("last reboot --since 2016-01-01 --until 2016-12-31 | grep -o '(.*)' | grep -v '-'| sed -e 's/(//g; s/)//g; s/+/:/g'", shell=True, stdout=subprocess.PIPE, universal_newlines=True)
mins_total = 0
for line in output.stdout.split('\n')[:-1]:
try:
(hrs, mins) = [int(k) for k in line.split(':')]
days = 0
except:
(days, hrs, mins) = [int(k) for k in line.split(':')]
mins_total += (days*24 + hrs)*60 + mins
print("Hours: " + str(mins_total/60))
print("Days: " + str(mins_total/60/24))
答案3
这是一个 awk + awk 版本:
last ... | awk '/reboot/{print $NF}' |
awk -F '[(+:)]' '
{
d += $(NF - 3); h += $(NF - 2); m += $(NF - 1)
}
END {
carry = m / 60; h += carry;
carry = h / 24; d += carry;
printf "%d days, %d hours, %d minutes\n", d, h % 24, m % 60
}'
last
最后一列的格式为(<days>+hours:minutes)
,其中,days+
如果周期少于 1 天,则删除。
这里,第一个awk
命令输出条目的最后一列,即感兴趣的持续时间reboot
。
对于第二条awk
命令:
FS
是[(+:)]
,即括号或者+
或者:
。因此,(h:m)
被拆分为、
h
、m
和(第一个和最后一个字段为空),
(d+h:m)
被拆分为、
d
、h
、m
和(同样,第一个和最后一个字段为空)。
- 然后我们取倒数第二个字段表示分钟,倒数第三个字段表示小时,倒数第四个字段表示天数。如果没有天数,则倒数第四个字段将是第一个空字段。因此,
0
在这种情况下我们只需添加即可。 - 然后,如果分钟和小时分别超过 60 和 24,我们将增加小时和天数。请注意,awk 会执行浮点除法,因此
h
和d
现在可能具有小数部分。 - 然后我们将数字打印为整数(
%d
),因此任何小数部分都会被忽略。
答案4
自 2023 年 5 月 22 日起,UBUNTU 和所有 *NIX 都有一个名为“ac”的命令。如果没有,请添加“acct”包。
Inspiron-ubnt:~$ ac
total 67.71
安装:
Inspiron-ubnt:~$ sudo apt install acct