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.