I wish to write a bash script that executes on start up Ubuntu 13.04 and starts motion whenever the screen is locked. Being a novice at bash scripting, I wasn't able to understand the various help sources available on the web and thereby write a script on my own. Anyways, I know that the following command is used to check if the system is locked:

gnome-screensaver-command -q | grep "is active"

But, if I use this command, I will have to periodically (say every 5-10 seconds) check the lock status. Is there a better alternative? Could someone provide me with a skeleton of the script?

So I could write the following script which starts the webcam once I lock the screen but does not stop it once sign back in. Any suggestions?

#!/bin/bash

while :
do
    sleep 2
    if (gnome-screensaver-command -q | grep "is active");
    then
        motion 2> ~/.motion/log
    elif (gnome-screensaver-command -q | grep "is inactive");
    then
        /etc/init.d/motion stop 1> /dev/null
    fi
done
  • You can use sleep 5 to wait 5 seconds before you check again. – dan08 Aug 9 '13 at 16:11
up vote 1 down vote accepted

I don't think that you can find a simple better alternative at gnome-screensaver-command -q command, but I found a solution to make your script to function as probably you expect:

#!/bin/bash

is_active=0

while :
do
    sleep 2
    if (gnome-screensaver-command -q | grep "is active");
    then
        if [ "$is_active" -eq "0" ];
        then
            is_active=1
            motion 2> ~/.motion/log &
        fi
    elif (gnome-screensaver-command -q | grep "is inactive");
    then
        if [ "$is_active" -eq "1" ];
        then
            is_active=0
            /etc/init.d/motion stop 1> /dev/null
        fi
    fi
done

Some explanation:

  • motion 2> ~/.motion/log command followed by & will start the motion process to run in terminal; without &, when the execution of the script reach to that line, this will remain hanged/blocked there.
  • you don't need to run at every 2 seconds motion 2> ~/.motion/log & or /etc/init.d/motion stop 1> /dev/null command, but only when the state of the screensaver is changing; for this reason other changes from the script.

gnome-screensaver emits some signals on dbus when something happens.

The following line, when run, prints a line whenever the screen is locked or unlocked:

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'"

On my machine, the following is printed when the screen is locked:

signal sender=:1.87 -> dest=(null destination) serial=20 path=/org/gnome/ScreenSaver; interface=org.gnome.ScreenSaver; member=ActiveChanged
   boolean true

And when unlocked, the following text is printed:

signal sender=:1.87 -> dest=(null destination) serial=22 path=/org/gnome/ScreenSaver; interface=org.gnome.ScreenSaver; member=ActiveChanged
   boolean false

Script to lock screen and start motion

To make use of this, we run the above command in the script and whenever something is printed we check if it was a screen lock or screen unlock action.

#! /bin/bash

function onScreenLock() {
    motion 2> ~/.motion/log &
}

function onScreenUnlock() {
    /etc/init.d/motion stop 1> /dev/null
}

dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | 
( 
    while true; 
    do 
        read X; 
        if echo $X | grep "boolean true" &> /dev/null; 
        then 
            onScreenLock(); 
        elif echo $X | grep "boolean false" &> /dev/null; 
        then 
            onScreenUnlock(); 
        fi
    done 
)

Source and further information:

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.