10

This is my attempt to make a script that will use a "mouse move" to prevent screen blanking while watching videos. I'm hoping to use the value for highest CPU% process in top and if CPU usage exceeds 5%, a mouse move should occur.

#!/usr/bin/env bash

sleep_period=60s 

while true; do
  if (( $(top -bn 1 | sed -nrs '8p' | awk '{ print $9 }') -gt 5 )); then 
    while (( $(top -bn 1 | sed -nrs '8p' | awk '{ print $9 }') -gt 5 )); do
      xdotool mousemove 0 100
      xdotool mousemove 0 50
      sleep ${sleep_period}
    done
  else
    sleep ${sleep_period}
  fi
done

Unfortunately, it does not work. The errors are like this:

[07:20 PM] /bin $ noo.sh
/home/vasa1/bin/noo.sh: line 6: ((: 0.0 -gt 5 : syntax error: invalid arithmetic operator (error token is ".0 -gt 5 ")
/home/vasa1/bin/noo.sh: line 6: ((: 6.4 -gt 5 : syntax error: invalid arithmetic operator (error token is ".4 -gt 5 ")

How do I fix this? (Please note that I'm not experienced in scripting.)


Based on answers here, I put together:

#!/usr/bin/env bash

sleep_period=5m 

while true; do
  if [[ $(top -bn 1 | sed -nrs '8p' | awk '{ print int($9) }') -gt 8 ]]; then 
    while [[ $(top -bn 1 | sed -nrs '8p' | awk '{ print int($9) }') -gt 8 ]]; do
      xset -dpms; xset s off
      xset +dpms; xset s on
      sleep ${sleep_period}
    done
  else
    sleep ${sleep_period}
  fi
done

Then, I reported this code over at Ubuntu Forums and Vaphell worked on it further. Below is Vaphell's version and is what I am using:

#!/usr/bin/env bash

sleep_period=5m 

while true; do
  if top -bn 1 | awk 'NR==8 { exit !($9>8); }'; then
    xset -dpms; xset s off
    xset +dpms; xset s on
  fi
  sleep ${sleep_period}
done
  • to start with, -gt expects integer operands, not floating point. and i'm not sure why you're using ((...)) rather than just [...]. or why you're using CPU% as the trigger...or even why you're extracting CPU% utilisation from a curses program like top rather than something like ps -heo %C --sort -%cpu | head -1 – cas Sep 18 '13 at 14:33
  • 5
    IMO, you would be better off finding out why your video player program isn't disabling the screensaver and fixing that. Which player do you use? (e.g. totem, vlc, ...) and what desktop/window-manager (gnome, xfce, lxde, kde, other) and which screen-saver. – cas Sep 18 '13 at 14:34
  • @CraigSanders there's a long standing bug that results in vlc not being able to communicate with gnome-sceensaver and maybe others. I haven't looked into it for a while but it used to drive me up the wall too. See here for example. – terdon Sep 18 '13 at 14:37
  • 1
    yeah, i've run into vlc/gnome issues before. iirc, i ended up using xset as suggested by Raphael below. – cas Sep 18 '13 at 15:02
  • @CraigSanders, 1 as I admitted in the last line of the question, I'm not experienced in scripting; 2 I want something that will work with GNOME Mplayer, Vlc, Firefox and Chrome without my intervention; 3 I'm using Openbox without a DE (but the distro is Lubuntu 13.04) so I'm guessing it's xscreensaver and I don't have gnome-screensaver installed. –  Sep 18 '13 at 16:53
  • 4
    Perhaps more than a bit related: http://xkcd.com/196/ – DanteTheEgregore Sep 18 '13 at 17:40
  • Aww, @ZachSmith, your comment was hidden, so I just went off and found that to post myself. I was going to just say Really? – TRiG Sep 18 '13 at 18:23
  • 3
    May I suggest that you simply install an application to prevent screen-blanking while videos are running? I use Caffeine, which works very well indeed. – Paddy Landau Sep 18 '13 at 19:49
  • @PaddyLandau, nice to see you here :) I do know about the existence of a lot of ready-to-use scripts and the Caffeine ppa. As you can see from the answers and comments, I'm learning a lot more this way than by using something out of the box. –  Sep 19 '13 at 02:41
  • @vasa1 Indeed, doing it yourself certainly teaches you plenty! – Paddy Landau Sep 19 '13 at 11:34

3 Answers3

9

You can use

xset -dpms; xset s off

to stop the screen from going black.

To enable this again use

xset +dpms; xset s on

So -dpms disables the the power energy saving features, which can turn off the whole monitor and s off turns off the screen saver feature of the X server.

This does not work with the xscreensaver, which was mentioned in the comments.

  • Doesn't that assume you are using xscreensaver? Will it work with any screensaver? Even DE ones like gnome-screensaver? – terdon Sep 18 '13 at 14:33
  • @terdon As far as I know this disables all types of screensavers. – Raphael Ahrens Sep 18 '13 at 14:41
  • I want something that doesn't need my intervention –  Sep 18 '13 at 16:56
  • @vasa1 as long as this works for your screensaver, it needs no more intervention than your script. You just run that command once and the screensaver is off. – terdon Sep 18 '13 at 17:04
  • @terdon, yes, but won't I need to turn it on again (in the same session)? –  Sep 18 '13 at 17:16
  • 2
    @vasa1 you could use this instead of the xdotool mousemove 0 100. – Raphael Ahrens Sep 18 '13 at 17:17
  • @RaphaelAhrens, how would the code look then? Would your first line replace the first xdotool and the second line replace the second one? And would everything else be the same? –  Sep 18 '13 at 17:28
  • I can confirm this does not work with xscreensaver and Cinnamon 1.8.8 – terdon Sep 18 '13 at 18:17
  • @terdon from the xscreensaver man page "As of version 3.28 (Feb 2001), the ~/.xscreensaver file controls the configuration of your display’s power management settings: if you have used xset(1) to change your power management settings, then xscreensaver will override those changes with the values specified in ~/.xscreensaver (or with its built-in defaults, if there is no ~/.xscreensaver file yet.)". I didn't know that, thanks. – Raphael Ahrens Sep 18 '13 at 18:25
  • Huh, neither did I :). I just saw it didn't work but I guess using the file should provide a workaround, thanks! – terdon Sep 18 '13 at 18:32
  • @vasa1 I would replace the until loop in @terdons answer with an if else. In the if I would use the test from the loop and if it is true then xset -dpms; xset s off and in the else I switch it back on. Mh should I write it in a new answer? – Raphael Ahrens Sep 18 '13 at 18:37
  • @RaphaelAhrens, as things stand, I've reverted to a version of the code I used originally but using the int idea provided by @drewbenn here and youroff and on xset codes in place of the mouse move ones. It now seems to work fine at least over a couple of hours last night in my specific situation. –  Sep 19 '13 at 02:50
  • @vasa1 would you like to share your solution for other people who have the same problem? – Raphael Ahrens Sep 19 '13 at 08:20
  • @RaphaelAhrens, please see the edit to my question. –  Sep 19 '13 at 11:36
6

You have a couple of issues, first, you will need 2 iterations of top each time, see my answer here and the bug report here.

The other problem is that bash does not do floating point, so if your CPU usage is something like 6.2, the .2 will break the script. Bash is simply not designed for 'complex' arithmetic operations. One way around this would be to move the >5 check inside your awk command:

#!/usr/bin/env bash

sleep_period=60s 

while true; do
    until top -bn 2 -d 0.01 | sed -nrs '8p' | awk '{if($9>5){exit 1}else{exit 0}}'; do
      xdotool mousemove 0 100
      xdotool mousemove 0 50
      sleep ${sleep_period}
    done
   sleep ${sleep_period}
done
terdon
  • 242,166
1

First, you need to install xdotool & rand. Example on Ubuntu:

sudo apt install xdotool rand

Then run this one-liner in a terminal (as user):

eval $(xdotool getdisplaygeometry --shell); while true; do xdotool mousemove `rand -M $WIDTH` `rand -M $HEIGHT` && sleep $((`rand -M 300` + 120)); done;
Pivert
  • 131