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
  • 32,237
jakfish
  • 23
  • 4

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
  • 32,237
  • This is incredibly helpful. Many, many thanks. I'm amazed at how much syntax is at your command. I've almost got your script running and I think I'll try to run it alongside a second script of tuptime

    I have only a new characters left for this comment, so I'll post the tuptime output in a second comment because I'm hoping you could show me how to awk/print (not to file, output only) the "System uptime" which apparently combines all uptimes between shutdowns.

    – jakfish Jun 21 '22 at 16:08
  • `[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`

    I'm playing this but I can't just print the 2h 52m

    [jake@P3 ~]$ sudo tuptime -S 2 | grep -m 1 'System uptime' | cut -c1-9,10-15 | awk '{print $0,$6}'

    – jakfish Jun 21 '22 at 16:13
  • @jakfish Try this tuptime | awk -F'=' '/System uptime:/ {print $2}' ... is that the output you want? ... If you want, you can add your script to your question and I will look into it and fix it as much as I can ... tomorrow though ... it's night time where I live :) – Raffa Jun 21 '22 at 16:23
  • Again, your assistance is invaluable. Right before your last post, I went with this: sudo tuptime -S 2 | grep -m 1 'System uptime' | cut -c36-41 | awk '{print $0,$6}'

    Which seems to work just like your command, but without listing the seconds, just hours and minutes.

    Sleep well, thanks again.

    – jakfish Jun 21 '22 at 16:41
  • You're very kind to look over my shutdown script. It's a shutdown after idle time, but before actual shutdown, it calls another script to find/save/close a Wine/MS Word doc (I posted over in wine forum but didn't get any hits, so I had to fumble mysel): – jakfish Jun 21 '22 at 19:24
  • `#!/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`

    – jakfish Jun 21 '22 at 19:27
  • 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 – jakfish Jun 21 '22 at 19:28
  • I apologize for the brutal format of the coding, but apparently, this is the best "Add comment" can do. – jakfish Jun 21 '22 at 19:29
  • tuptime | awk -F'=' '/System uptime:/ {print $2}' Your command is a better one than mine. It works better in xfce/panel/genmon. Is there a way to cut the seconds, leaving just the hours/minutes? – jakfish Jun 21 '22 at 20:01
  • sudo tuptime | awk -F'=' '/System uptime:/ {print substr($2, 1, length($2)-3)}' 1h 38m This seems to work, combining your command with substr – jakfish Jun 21 '22 at 20:31
  • @jakfish I have added these comments to your question ... You can edit your question too, please see site help ... I answered with as much explanation as I could. – Raffa Jun 22 '22 at 07:56
  • @jakfish To start your script after login and kill it on logout, change the method you are currently using to start your script to ---> running it by creating a new startup application and adding a line like bash /path/to/your/scriptfile in the "command field" see this answer for example ... you might need, however, to specify the full path to the bash executable on your system that you can find with which bash ... I spotted your comment under the other member's answer by coincidence :) as I don't get notification unless a comment is under mine. – Raffa Jun 23 '22 at 07:15
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
  • I'm so grateful for all this help. You've fixed a ton of things and taught me just as much. I put in all your script edits and everything seems fine except for one oddity (the oddity is persistent even with my original shutdown script) -- logging out brings me to the log-in page but then the machine shuts down without prompt. When I kill the shutdown script before logging out, logout/login is fine.

    Is this a xprintidle issue or something in my script? Obviously, I can work around it by scripting a kill shutdown, then a logout command, but I'm interested in your opinion.

    Again, thank you.

    – jakfish Jun 22 '22 at 14:36