3

I'm running Ubuntu 12.04 and bash. I've written a pair of shell scripts that allow me to set an alarm which, after ringing, unsets itself. The first, alarmset, allows me to enter a time and modifies the alarm line in my user crontab. That line launches the second script, alarmring, which launches a radio player in a browser window and then comments out the alarm line in the crontab.

alarmring is behaving strangely. If I run it myself directly, it performs both actions: it launches the browser window and edits the crontab. But if I run alarmset, when the crontab launches alarmring at the appointed time, alarmring edits the crontab, but does not launch the browser window.

Finally, when crontab runs alarmring, it ignores the set -x command, whereas when I run it directly, set -x is executed. So it's as though the crontab is skipping the first ten lines.

Any ideas on what's going on? I'll paste the two scripts and the crontab below.

alarmset:

#!/bin/bash

# alarmset

set -x

usage()
{ echo "alarmset [ hour minute | -h ]" }

editcrontab() 
{ 
    echo $'/alarmring/s/^\(.*\)\(\* \* \*\)/'$2$' '$1$' \\2/' > ~/Documents/crontab_script.txt 
    crontab -l | sed --file=/home/username/Documents/crontab_script.txt > ~/Documents/new_crontab.txt crontab ~/Documents/new_crontab.txt 
}

### MAIN 
case $# in 
    2 ) editcrontab $1 $2 ;; 
    * ) usage 
        exit ;; 
esac

set +x

alarmring:

#!/bin/bash

# alarmring

set -x

env DISPLAY=:0

# Ring the alarm : launch BBC World Service in Firefox 
firefox --new-window http://www.bbc.co.uk/radio/player/bbc_world_service

# Unset the alarm : comment out the alarm line in the crontab 
crontab -l | sed '/alarmring/s/^/#/1' > ~/Documents/new_crontab.txt 
crontab ~/Documents/new_crontab.txt

set +x

crontab:

SHELL=/bin/bash 
PATH=~/bin:/usr/bin:/bin 
# 
# m h dom mon dow command 
53 07 * * * /home/username/bin/alarmring

3 Answers 3

3

To run a GUI program, you need to set the DISPLAY environment variable, and possibly XAUTHORITY as well. See Open a window on a remote X display (why "Cannot open display")? for more information.

~ meaning your home directory is a shell feature, you can't use it in a crontab. For the same reason, you can't use HOME. Use the full path for your home directory:

PATH=/home/username/bin:/usr/bin:/bin

With bash as your shell, ~ actually works, because bash expands ~ in the value of PATH. But that's an oddity of bash, no other shell or other program works this way.

The command env DISPLAY=:0 displays the current environment, except with DISPLAY set to :0. That isn't useful. You presumably meant export DISPLAY=:0.

Your arrangement is very complicated. Cron is designed for repeating tasks. If you want to schedule a background job just once, use at.

at 7:53 <<EOF
firefox --new-window http://www.bbc.co.uk/radio/player/bbc_world_service
EOF

At retains the DISPLAY environment variable, so provided you run the at command from the GUI where you want Firefox to display a window, you don't need to set it manually.

0
0

Entries in the systems crontab (/etc/crontab) or to the directories (/etc/cron.d -or- /etc/cron.hourly, etc.) run as root. It's probably the case that root doesn't have the ability to access a given user's display by default.

I'd suggest making crontab entries using the user's ability to add crontabs. This can be accomplished by using the command crontab -e in a shell logged in as the specified user.

The command crontab -e will open a text editor (usually vi or vim) where you can add entries using the same syntax that you'd use to add entries to the systems /etc/crontab file.

This tutorial covers the basics of adding crontab entires.

Also when adding a user's crontab via crontab -e and your script needs access to your display (say you're launching a GUI), you'll need to set the environment variable (export DISPLAY=:0.0) so that the GUI get's directed to the correct display.

For example

% crontab -e

And add the following line:

53 07 * * * export DISPLAY=:0.0;/home/username/bin/alarming
5
  • This isn't a system crontab, though; it's my user crontab. I'll clarify. Apr 6, 2013 at 17:13
  • I had to add a semicolon, so that it now reads 53 07 * * * export DISPLAY=:0.0;/home/username/bin/alarming. But, yes, that worked. Thank you. Go ahead & make it an answer. Apr 6, 2013 at 17:34
  • Yeah I should've mentioned that. You can also wrap the entire line in it's own script. Glad it worked, updated my answer to include the additional details.
    – slm
    Apr 6, 2013 at 17:46
  • 1
    Note to the curious: I've learned that, in Ubuntu/Debian, this task is nicely handled by the at command. Apr 6, 2013 at 19:27
  • 2
    the at command is ubiquitous across pretty much all the unices.
    – slm
    Apr 6, 2013 at 22:14
0
$ xauth extract - :0 | sudo xauth -f /root/.Xauthority merge -

They also run from a different tty so you need to

$ DISPLAY=:0 xclock

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .