LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Python gconf not working when ran as root (http://www.linuxquestions.org/questions/programming-9/python-gconf-not-working-when-ran-as-root-784285/)

figure002 01-23-2010 07:06 PM

Python script cannot reach X server when executed by cron
 
Hello all. So I have yet another annoying problem.

This is the case. I run openSUSE 11.2 with GNOME. I want my desktop wallpaper to automatically cycle on a fixed interval. So I found this script (change-background.py), edited it to match my needs, and put it in my home bin directory. The script runs fine.

change-background.py
Code:

#!/usr/bin/env python
#
# change-background.py
#
#
# A script to change to a random background image
#
#(c) 2004, Davyd Madeley <davyd@madeley.id.au>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2, or(at your option)
#  any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

backgrounds = "/home/serrano/wallpapers"

import sys
import gconf
import os
import random
import mimetypes

def get_files_recursively(rootdir):
    """Recursively get a list of files from a folder."""
    fileList = []

    for root, subFolders, files in os.walk(rootdir):
        for file in files:
            fileList.append(os.path.join(root,file))

    return fileList

# Get the files from the backgrounds folder.
dir_items = get_files_recursively(backgrounds)

# Check if the background items are actually images. Approved files are
# put in 'items'.
items = []
for item in dir_items:
    mimetype = mimetypes.guess_type(item)[0]
    if mimetype and mimetype.split('/')[0] == "image":
        items.append(item)

# Get a random background item from the file list.
item = random.randint(0, len(items) - 1)

# Create a gconf object.
client = gconf.client_get_default()

# Get the current background used by GNOME.
current_bg = client.get_string("/desktop/gnome/background/picture_filename")

# Make sure the random background item isn't the same as the background
# currently being used.
while(items[item] == current_bg):
    item = random.randint(0, len(items) - 1)

# Finally, set the new background.
client.set_string("/desktop/gnome/background/picture_filename", items[item])
sys.exit()

So the next step, is to make it run, let's say every minute (to test it first). We can use 'cron' for this job. So this is what I did:
Code:

serrano@saibot:~> sudo crontab -u serrano -e
In vim, added the following two lines:
* * * * * touch /home/serrano/CRON_WORKS.txt
* * * * * /home/serrano/bin/change-background.py
In vim, save and exit.
crontab: installing new crontab

If everything works ok, the wallpaper should now change every minute. But everything is not ok. Cron works fine, because I can tell from the file 'CRON_WORKS.txt' being created in my home directory. But the wallpaper didn't change.

I think the problem lies in the fact that cron runs 'change-background.py' as root. And that's where the 'change-background.py' stops working:
Code:

serrano@saibot:~> su root
Password:
saibot:/home/serrano # change-background.py
Traceback (most recent call last):
  File "/home/serrano/bin/change-background.py", line 61, in <module>
    current_bg = client.get_string("/desktop/gnome/background/picture_filename")
glib.GError: Failed to contact configuration server; some possible causes are that you need to enable TCP/IP networking for ORBit, or you have stale NFS locks due to a system crash. See http://projects.gnome.org/gconf/ for information. (Details -  1: Failed to get connection to session: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.)
saibot:/home/serrano #

Does anyone know how I can make the script working, so it works even when ran as root? Or is there a way to make cron run the script as a different user?

ozanbaba 01-24-2010 12:13 PM

i don't know which cron you got, but it prorbably supports this;
Code:

* * * * * serrano touch /home/serrano/CRON_WORKS.txt
* * * * * serrano /home/serrano/bin/change-background.py

this will make them run as user serrano

figure002 01-24-2010 04:59 PM

Quote:

Originally Posted by ozanbaba (Post 3838835)
i don't know which cron you got, but it prorbably supports this;
Code:

* * * * * serrano touch /home/serrano/CRON_WORKS.txt
* * * * * serrano /home/serrano/bin/change-background.py

this will make them run as user serrano

The cron jobs wouldn't work after the change. But it seems I was wrong about cron running the jobs as root. I checked the owner of 'CRON_WORKS.txt' and it was 'serrano', not root. So the problem can't be caused by the script being run as root.

I've posted the same problem in another thread, and someone mentioned that this might be caused by cron denying the job's access to $DISPLAY. I don't really know what that means though..

ozanbaba 01-25-2010 02:40 AM

Quote:

Originally Posted by figure002 (Post 3839041)
and someone mentioned that this might be caused by cron denying the job's access to $DISPLAY. I don't really know what that means though..

$DISPLAY variable is defined by X to let programs know the display. if it's not there, your program can not reach X window

mddirba 08-03-2010 11:40 AM

I ran into this problem as well. The fix is to set you DISPLAY variable in crontab. So your crontab should be as follows:

* * * * * serrano DISPLAY=:0.0 /home/serrano/bin/change-background.py

figure002 08-04-2010 06:41 AM

Quote:

Originally Posted by mddirba (Post 4054272)
I ran into this problem as well. The fix is to set you DISPLAY variable in crontab. So your crontab should be as follows:

* * * * * serrano DISPLAY=:0.0 /home/serrano/bin/change-background.py

That did the trick! Thank you for providing the fix :D

I should note however that the username in the crontab rule is not necessary if you use the -u <username> switch to run crontab.


All times are GMT -5. The time now is 03:00 PM.