Как узнать общее время, проведенное на ноутбуке в этом году?
Мне интересно узнать общее время, которое я потрачу на работу над ноутбуком в 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)
Теперь, как мне это сложить?
4 ответа
Вот версия 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), поэтому любая дробная часть игнорируется.
Попытка использования 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"
Вот реализация 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))
По состоянию на 22 мая 2023 года в UBUNTU и всех *NIX есть команда «ac». Если недоступен, добавьте пакет «acct».
Inspiron-ubnt:~$ ac
total 67.71
Установка:
Inspiron-ubnt:~$ sudo apt install acct