2

Because my umpc handles suspend/hibernation poorly, I've had to script a shutdown after timed idle.

The main script:

#!/bin/bash

idletime=$((15601000)) # 15 min in milliseconds #idletime=$((520330)) # about one minute, for testing idle=0 while [ $idle -lt $idletime ];do
idle=xprintidle sleep 1 done /home/jake/Scripts_Icons/Word_Shutdown sleep 2 sudo shutdown -P now

The Word_Shutdown script:

#!/bin/bash

if test $(wmctrl -l | grep "Microsoft Word" 2>&1 | wc -l) -eq 1; then
wmctrl -a "Microsoft Word"
sleep .2
xdotool keydown 0xffea + key 4
sleep .2
xdotool keyup 0xffea
sleep .2
xdotool key y fi

It works, but in order to monitor the battery life properly, I would like my uptimes during the sessions on one battery charge to be combined into one uptime.

Is that possible? I see that tuptime will show the uptime of the previous session and start monitoring the uptime of the current session. Is there a way to combine these outputs into a single readout eg 3hr 4 min ?

The tuptime command output:

[jake@P3 ~]$  sudo tuptime -S 2 
System startups:    8  since  06:14:53 PM 06/20/2022 
System shutdowns:   0 ok  +  7 bad 
System life:            17h 50m 4s

System uptime: 16.15% = 2h 52m 46s System downtime: 83.85% = 14h 57m 18s

Average uptime: 21m 36s Average downtime: 2h 8m 11s

Current uptime: 2h 9m 1s since 09:55:56 AM 06/21/2022

The "System uptime" apparently combines all uptimes between shutdowns.

I have tried:

tuptime | awk -F'=' '/System uptime:/ {print $2}'

It works but, prints the seconds and the leading space as well i.e 2h 52m 46s. Is there a way to cut the seconds and the leading white space, leaving just the hours and minutes i.e. 2h 52m?

Or does uptime itself have a handle that can similarly jiggled?

Raffa
  • 34,963
jakfish
  • 23

2 Answers2

1

It works, but in order to monitor the battery life properly, I would like my uptimes during the sessions on one battery charge to be combined into one uptime.

In order to monitor the battery life properly:

  • Identify your battery's device reference(name) with upower -e like so:

    upower -e | grep -i "batt"
    
  • Get battery information by using upower -i with the reference(name) of your battery like so:

    upower -i /org/freedesktop/UPower/devices/battery_BAT0
    
  • Refine the upower -i output to get only state like so:

    awk '/state:/ {print $2}' <(upower -i /org/freedesktop/UPower/devices/battery_BAT0)
    
  • Refine the upower -i output to get only percentage without "%" like so:

    awk '/percentage:/ {print 0+$2}' <(upower -i /org/freedesktop/UPower/devices/battery_BAT0)
    
  • Use the above knowledge in a script that checks every five minutes to run your shutdown command (replace # Your shutdown command here with your actual command) when your battery charge reaches 8% or less while it is in the discharging state like so:

#!/bin/bash

while true; do state="$(awk '/state:/ {print $2}' <(upower -i /org/freedesktop/UPower/devices/battery_BAT0))" percentage="$(awk '/percentage:/ {print 0+$2}' <(upower -i /org/freedesktop/UPower/devices/battery_BAT0))" [ "$state" == "discharging" ] && [ "$percentage" -le "8" ] && # Your shutdown command here sleep 300 done

Because my umpc handles suspend/hibernation poorly, I've had to script a shutdown after timed idle.

The main script:

#!/bin/bash ...

  • Your main script uses back ticks `...` for command substitution:

    idle=`xprintidle`
    

    While it will still work, back ticks for command substitution is considered a legacy feature(old and might get deprecated in the future) in bash so I recommend using $(...) instead like so:

    idle=$(xprintidle)
    
  • The sleep 1 call is too short for such uncritical task ... so I recommend extending it to say 30 seconds or even one minute like so:

    sleep 1m
    

The Word_Shutdown script:

#!/bin/bash ...

  • Your Word_Shutdown script has two issues in this part:

    if test $(wmctrl -l | grep "Microsoft Word" 2>&1 | wc -l) -eq 1; then
    

    First, you don't need to use grep "Microsoft Word" 2>&1 | wc -l ... grep -c "Microsoft Word" 2>&1 will output the same result.

    Second, quote the command substitution used directly in the if evaluation part to prevent possible word splitting like so:

    if test "$(wmctrl -l | grep -c "Microsoft Word" 2>&1)" -eq 1; then
    

I have tried:

tuptime | awk -F'=' '/System uptime:/ {print $2}'

It works but, prints the seconds and the leading space as well i.e
2h 52m 46s. Is there a way to cut the seconds and the leading white space, leaving just the hours and minutes i.e. 2h 52m?

Yes, and even better and future proof( e.g. if System uptime contains more than 3 fields e.g. 4d 22h 31m 54s) like so:

tuptime | awk '/System uptime:/  {for (i=1; i < NF; i++) {if (i > 4) {if (i < (NF - 1)) printf("%s ", $i); else print $i}}}'

The "System uptime" apparently combines all uptimes between shutdowns.

That is correct.

Or does uptime itself have a handle that can similarly jiggled?

Maybe, the -s option will become handy in your case ... from man tuptime:

-s | --seconds Output time in seconds and epoch

Raffa
  • 34,963
1

Tuptime could narrow the range in their reports. As you need the current and just the previous one, use tuptime -S -1, check it that is right with table output -t.

And to calculate both uptimes together:

tuptime -S -1 --csv | grep 'System uptime' | cut -d\" -f6 | awk -F\m '{print $1"m"}'

Use the Tuptime csv output to parse it easily, match the target line, cut the field and extract the text before 'm'.

rfmoz
  • 156