จะหาเวลาทั้งหมดที่ฉันใช้กับแล็ปท็อปของฉันในปีนี้ได้อย่างไร


17

ฉันสนใจที่จะรู้ว่าเวลาทั้งหมดที่ฉันใช้ไปกับการทำงานกับแล็ปท็อปของฉันในปี 2559

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

@kashish 1 วัน, 6 ชั่วโมง, 41 นาที
muru

สิ่งนั้นคือwtmpล็อก (ซึ่งเป็นสิ่งที่คุณเห็นในเอาต์พุตของlastคำสั่ง) ถูกตั้งค่าให้หมุนรายเดือน (เป็น/etc/logrotate.conf) ซึ่งหมายความว่าหลังจากผ่านช่วงเวลาหนึ่งไปแล้วล็อกที่เก่าที่สุดจะถูกลบ กล่าวอีกนัยหนึ่งสิ่งที่คุณพยายามทำlastมันจะไม่ถูกต้อง
Sergiy Kolodyazhnyy

@Serg ฉันได้ปิดใช้งาน logrotate สำหรับ wtmp เป็นเวลามากกว่าหนึ่งปีแล้วที่ฉันทำเช่นนั้นและขนาดไฟล์ปัจจุบันคือ 3.7M ดังนั้นฉันไม่เห็นเหตุผลใด ๆ ว่าทำไมจึงควรหมุนเป็นรายเดือน ;)
daltonfury42

@ daltonfury42 หากปิดใช้งานอยู่มันจะไม่หมุน ผู้ใช้ส่วนใหญ่ไม่ทำเช่นนั้น
Sergiy Kolodyazhnyy

คำตอบ:


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"
  • ครั้งแรกที่ uptimes จากการรีบูตครั้งล่าสุดมีการระบุไว้และจัดรูปแบบเพื่อแยกข้อมูลวันชั่วโมงนาทีและข้อมูลที่สอง tempนี้จะถูกบันทึกไว้แล้วใน
  • มีการตั้งค่าวันที่อ้างอิงปลอมที่เรียกว่า org = 2015-01-01ซึ่งจะเพิ่มสถานะการออนไลน์ปัจจุบัน
  • จากนั้น uptimes สะสมทั้งหมดจะถูกเพิ่มเข้าไปในตัวแปร new
  • ระยะเวลาระหว่าง orgและ uptime เน็ตnewพบความแตกต่าง

เอาท์พุท:

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

สคริปต์ต่อไปนี้สำหรับ uptime ในตรงหนึ่งปีนับจากวันสคริปต์ที่มีการเรียกใช้

#!/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
อย่างใดฉันชอบทุบตีสคริปต์ แต่ฉันรู้ว่าที่นี่ว่าคำตอบที่สง่างามมากขึ้นเป็นไปได้
ankit7540

ตามสคริปต์ของคุณฉันใช้จ่าย 2258 วัน, 1 ชั่วโมง, 15 นาทีออนไลน์เมื่อปีที่แล้ว
daltonfury42

แก้ไขข้อผิดพลาด โค้ดถูกย่อขนาดเป็น 8 บรรทัด
ankit7540

5

นี่คือการนำ python มาใช้ในสิ่งที่ฉันต้องการ แต่ฉันมั่นใจว่ามีวิธีที่ยอดเยี่ยมในการใช้ 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
“ ฉันแน่ใจว่ามีวิธีที่ยอดเยี่ยมในการทำกับ bash” IMHO Python เป็นตัวเลือกที่ดีกว่า Bash นั้นดีสำหรับการปรับเปลี่ยนไฟล์ไม่ใช่สำหรับการคำนวณ
Melebius
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.