Як знайти загальний час, який я провів на своєму ноутбуку в цьому році?


17

Мені цікаво дізнатися загальний час, який я витрачаю працюючи на своєму ноутбуку в 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 + 06: 41)?
кашиш

@kashish 1 день, 6 годин, 41 хвилина
муру

Річ у тім, що wtmpжурнали (це те, що ви бачите у результаті lastкоманди) встановлюються щомісяця (in /etc/logrotate.conf), тобто після закінчення певного періоду найдавніший журнал видаляється. Іншими словами, що б ви не намагалися зробити last, це не буде точно
Сергій Колодяжний,

@Serg Я вимкнув logrotate для wtmp. Минув уже не один рік, як я це зробив, і розмір файлу наразі становить 3,7 млн. Тож я не бачу жодної причини, чому він повинен змінюватися щомісяця. ;)
daltonfury42

@ daltonfury42 Якщо його відключити, він не обертається. Більшість користувачів цього не роблять.
Сергій Колодяжний

Відповіді:


5

Ось версія 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команди:

  1. FSє [(+:)], тобто, дужки або + або : . Таким чином, (h:m)розщеплюється на , h, mі (перший і останні поля порожні), і (d+h:m)діляться на , d, h, mі (знову ж , перший і останні порожній).
  2. Потім ми беремо друге останнє поле хвилин, третє - останнє години і четверте - останнє протягом днів. Четверте останнє поле буде першим, порожнім, поле, якщо днів немає. Отже, ми просто додамо 0в цьому випадку.
  3. Потім ми підбиваємо години та дні, якщо хвилини та години перевищують 60 та 24 відповідно. Зверніть увагу , що AWK робить з плаваючою точкою поділу, так hі в dданий час може мати дробові частини.
  4. Потім ми друкуємо числа у вигляді цілих чисел ( %d), тому будь-яка дробова частина ігнорується.

8

Спробуйте з bash script і розширити свою команду. Я використовую 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"

1
Якось мені подобаються сценарії bash, але тут я знаю, що можливі більш елегантні відповіді.
ankit7540

Згідно з вашим сценарієм, я минулого року проводжу в Інтернеті 2258днів, 01 годин, 15 хвилин.
daltonfury42

Виправлена ​​помилка Код ущільнений до 8 рядків.
ankit7540

5

Ось реалізація пітону того, що я хочу, але я впевнений, що є елегантний спосіб зробити це з 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
"Я впевнений, що є елегантний спосіб зробити це з басом" IMHO Python - кращий вибір. Bash хороший для файлових маніпуляцій, а не для обчислень.
Мелебій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.