Как получить реальное время работы?

Есть ли простой способ рассчитать время безотказной работы системы без учета периода? Я хотел бы посчитать время, которое я провел перед компьютером.

0 ответов

С одной стороны, этот ответ опоздал на шесть лет, с другой стороны, если интернет вечен, это мгновение ока!

Вы можете получить реальное время безотказной работы с этим небольшим скриптом bash:

$ suspendtime
Oct 31 05:55:19 to Oct 31 16:54:26 lasting 39,547 seconds
Oct 31 23:21:21 to Nov 01 04:29:12 lasting 18,471 seconds
  (... SNIP ...)
Nov 07 05:53:36 to Nov 07 16:37:36 lasting 38,640 seconds
Nov 07 21:07:28 to Nov 08 05:08:52 lasting 28,884 seconds

Linux uptime 693,600 seconds (8 days, 40 minutes)
16 Suspends 457,547 seconds (5 days, 7 hours, 5 minutes, 47 seconds)
Real uptime 236,053 seconds (2 days, 17 hours, 34 minutes, 13 seconds)

Linux сообщит о времени безотказной работы за 8 дней и 40 минут. Реальное время работы (после вычитания времени ожидания) составляет около 2 дней и 18 часов.


suspendtime скрипт bash

Вот код, который вы можете скопировать в вашу систему:

#!/bin/bash

# NAME: suspendtime
# PATH: $HOME/askubuntu/
# DESC: For: https://Ask-ubuntu.ru/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

# 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 '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 ))
    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 %'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 Команда regex выполняет тяжелую работу, возвращая 32 системных сообщения, относящихся к приостановке из 19330 системных сообщений, записанных (в моей системе).

Спустя годы вышеуказанный сценарий требует обновления. Сообщения systemd и команда date больше не совместимы - как объясняется в комментариях к верхнему скрипту. Я взял его за основу и изменил. Журнал возвращает дату как "Mai 03 ...", которая не может быть обработана по дате. Чтобы обойти эту проблему, я подделал год и месяц - поэтому он не будет правильно считать, если месяц будет изменен в режиме ожидания.... Может быть, кто-то это изменит.

#!/bin/bash

# NAME: suspendtime
# PATH: $HOME/askubuntu/
# DESC: For: https://Ask-ubuntu.ru/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"   
Другие вопросы по тегам