Come trovare il tempo totale trascorso sul mio laptop quest'anno?


17

Sono interessato a conoscere il tempo totale trascorso a lavorare sul mio laptop nel 2016.

last reboot --since 2016-01-01 --until 2016-12-31 | grep -o '(.*)' | grep  -v '-'

mi dà il tempo di attività totale del laptop in questo formato:

(01:33) 
(04:40) 
(01:31) 
(1+06:41) 
(02:47) 
(00:30)

Ora come posso aggiungerlo?


puoi dirmi il significato di (1 + 06: 41)?
— kashish il

@kashish 1 giorno, 6 ore, 41 minuti
— muru

Il fatto è che i wtmpregistri (che è quello che vedi nell'output del lastcomando) sono impostati per ruotare mensilmente (in /etc/logrotate.conf), il che significa che dopo un certo periodo di tempo, il registro più vecchio viene eliminato. In altre parole, qualunque cosa tu stia cercando di fare last, non sarà preciso
— Sergiy Kolodyazhnyy,

@Serg Ho disabilitato logrotate per wtmp. È passato più di un anno da quando l'ho fatto e la dimensione del file è attualmente di 3,7 milioni. Quindi non vedo alcun motivo per cui dovrebbe essere ruotato mensilmente. ;)
— daltonfury42

@ daltonfury42 Se disabilitato, non ruoterà. La maggior parte degli utenti non lo fa.
— Sergiy Kolodyazhnyy,

Risposte:


5

Ecco una versione di 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
        }'

lastL'ultima colonna è nel formato (<days>+hours:minutes), dove days+viene rilasciata se il periodo è inferiore a 1 giorno.

Qui, il primo awkcomando genera l'ultima colonna, la durata di interesse, per le rebootvoci.

Per il secondo awkcomando:

  1. FSè [(+:)], cioè, tra parentesi o + o : . Quindi, (h:m)è diviso a , h, me (prima e ultima campi vuoti), ed (d+h:m)è diviso a , d, h, me (ancora una volta, prima e l'ultima campi vuoti).
  2. Quindi prendiamo il penultimo campo per minuti, il terzo per ore e il quarto per giorni. Il quarto campo sarà il primo campo vuoto se i giorni non sono presenti. Quindi, aggiungeremo semplicemente 0in questo caso.
  3. Quindi aumentiamo di ore e giorni se minuti e ore sono rispettivamente superiori a 60 e 24. Si noti che awk esegue la divisione in virgola mobile, quindi he dora può avere parti frazionarie.
  4. Quindi stampiamo i numeri come numeri interi ( %d), quindi qualsiasi parte frazionaria viene ignorata.

8

Provare con bash script ed estendere il tuo comando. Uso dateutilsper sommare la durata.

Quindi per usare questo script è necessario il dateutilspacchetto disponibile attraverso apt. ( sudo apt install dateutils)

Questo script tiene conto anche del tempo di attività corrente (sessione attuale), quindi più accurato. I secondi non vengono conteggiati. L'unità più bassa riportata è minuto.

#!/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"
  • Innanzitutto i tempi di attività dall'ultimo riavvio sono elencati e formattati per estrarre il giorno, le ore, i minuti e le seconde informazioni. Questo viene quindi salvato in temp.
  • Viene impostata una data falsa di riferimento chiamata org = 2015-01-01a cui viene aggiunto il tempo di attività corrente.
  • Quindi tutti i tempi di attività cumulativi vengono aggiunti alla variabile new
  • La durata tra orge il tempo di attività netto newviene rilevata per differenza.

Produzione:

vayu@helix:$ ./uptime_record.sh
Total run time (days:hours:minutes)
57d 20h 36m

Lo script seguente è per il tempo di attività in esattamente un anno dal giorno in cui lo script viene eseguito .

#!/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
In qualche modo mi piacciono gli script bash, ma so qui che sono possibili risposte più eleganti.
— ankit7540,

Secondo la tua sceneggiatura, ho trascorso 2258 giorni, 01 ore, 15 minuti online l'anno scorso.
— Daltonfury42

Errore risolto. Codice compattato su 8 righe.
— ankit7540,

5

Ecco un'implementazione di Python di ciò che voglio, ma sono sicuro che esiste un modo elegante per farlo con 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
"Sono sicuro che esiste un modo elegante per farlo con bash" IMHO Python è una scelta migliore. Bash è utile per manipolazioni di file, non per calcoli.
— Melebio
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.