Bagaimana menemukan total waktu yang saya habiskan untuk laptop saya di tahun ini?

17

Saya tertarik mengetahui total waktu yang saya habiskan untuk mengerjakan laptop pada tahun 2016.

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

memberi saya total waktu kerja laptop dalam format ini:

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

Sekarang bagaimana cara menambahkannya?

daltonfury42
sumber
dapatkah Anda memberi tahu saya makna (1 + 06: 41)?
Kashish
@ashash 1 hari, 6 jam, 41 menit
muru
Masalahnya adalah bahwa wtmplog (yang adalah apa yang Anda lihat dalam output dari lastperintah) diatur untuk memutar bulanan (dalam /etc/logrotate.conf), yang berarti bahwa setelah periode waktu tertentu, log tertua dihapus. Dengan kata lain, apa pun yang Anda coba lakukan last, itu tidak akan akurat
Sergiy Kolodyazhnyy
@Serg Saya telah menonaktifkan logrotate untuk wtmp. Sudah lebih dari setahun sejak saya melakukan itu, dan ukuran file saat ini 3,7 juta. Jadi saya tidak melihat alasan mengapa harus diputar setiap bulan. ;)
daltonfury42
@ daltonfury42 Jika dinonaktifkan, ini tidak akan berputar. Sebagian besar pengguna tidak melakukan itu.
Sergiy Kolodyazhnyy

Jawaban:

5

Berikut ini adalah versi 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
        }'

lastKolom terakhir adalah dalam format (<days>+hours:minutes), di mana days+dijatuhkan jika periode kurang dari 1 hari.

Di sini, awkperintah pertama menampilkan kolom terakhir, durasi bunga, untuk rebootentri.

Untuk awkperintah kedua :

  1. FSadalah [(+:)], yaitu, tanda kurung atau + atau : . Jadi, (h:m)dibagi untuk , h, mdan (pertama dan bidang terakhir kosong), dan (d+h:m)dibagi untuk , d, h, mdan (sekali lagi, pertama dan bidang terakhir kosong).
  2. Lalu kami mengambil bidang kedua terakhir selama beberapa menit, ketiga terakhir untuk jam dan keempat terakhir untuk hari. Bidang keempat terakhir akan menjadi bidang pertama, kosong, jika hari tidak ada. Jadi, kami hanya akan menambahkan 0dalam kasus ini.
  3. Kemudian kami menambah jam dan hari jika menit dan jam masing-masing di atas 60 dan 24. Perhatikan bahwa awk melakukan pembagian titik mengambang, jadi hdan dsekarang mungkin memiliki bagian fraksional.
  4. Lalu kami mencetak angka sebagai bilangan bulat ( %d), sehingga setiap bagian fraksional diabaikan.
muru
sumber
8

Mencoba dengan skrip bash dan memperluas perintah Anda. Saya gunakan dateutilsuntuk menambah durasi waktu.

Oleh karena itu untuk menggunakan script ini salah satu kebutuhan dateutilspaket yang tersedia melalui apt. ( sudo apt install dateutils)

Script ini memperhitungkan uptime saat ini (sesi saat ini) juga, karenanya lebih akurat. Detik tidak dihitung. Unit terendah yang dilaporkan adalah menit.

#!/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"
  • Pertama kali uptime dari reboot terakhir terdaftar dan diformat untuk mengekstrak informasi hari, jam, menit dan kedua. Ini kemudian disimpan dalam temp.
  • Tanggal palsu referensi disetel disebut org = di 2015-01-01mana uptime saat ini ditambahkan.
  • Kemudian semua waktu up kumulatif ditambahkan ke variabel new
  • Durasi antara orgdan waktu aktif bersih newditemukan berdasarkan perbedaan.

Keluaran:

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

Script berikut adalah untuk uptime tepat dalam satu tahun dari hari script dijalankan .

#!/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"
ankit7540
sumber
1
Entah bagaimana saya suka skrip bash, tapi saya tahu di sini bahwa jawaban yang lebih elegan dimungkinkan.
ankit7540
Menurut skrip Anda, saya menghabiskan 2258 hari, 01 jam, 15 menit online tahun lalu.
daltonfury42
Kesalahan diperbaiki. Kode dipadatkan menjadi 8 baris.
ankit7540
5

Berikut ini adalah implementasi python dari apa yang saya inginkan, tetapi saya yakin ada cara yang elegan untuk melakukannya dengan 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))
daltonfury42
sumber
3
"Saya yakin ada cara yang elegan untuk melakukannya dengan bash" IMHO Python adalah pilihan yang lebih baik. Bash baik untuk manipulasi file, bukan untuk perhitungan.
Melebius