1

So I've tried to run a shell script via crontab.

My Crontabs look like this: 00 20 * * * $HOME/Bilder/Hintergründe/.background_skript/background_night.sh

and my background_day.sh looks like this:

`#!/bin/bash wallpaper="$HOME/Bilder/Hintergründe/appa_night.jpg"

gsettings set org.gnome.desktop.background picture-uri-dark file:///"$wallpaper"`

I have already assigned the chmod rights with: chmod +x background_night.sh.

It also works fine if I run it directly with the shell.

And the grep CRON /var/log/syslog looks like this:

May 25 15:07:01 sebs-thinkpad CRON[90433]: (seb) CMD (sh /home/seb/Bilder/Wallpaper/.background_skript/background_night.sh) May 25 15:08:01 sebs-thinkpad CRON[90472]: (CRON) info (No MTA installed, discarding output)

I'm not sure what I've done wrong.

2 Answers 2

1

Use > cron.log 2>&1 to have the cronjob write its output to a file, so that you could see the error messages it produces. (Some cron daemons automatically write the output to syslog when mail is not available; yours apparently doesn't.)

Most likely the problem is that 'gsettings set' works via D-Bus (the session bus, specifically, not the system bus) and usually requires either one of DBUS_SESSION_BUS_ADDRESS or XDG_RUNTIME_DIR environment variables to be present (depending on setup).

First of all, though:

  • If your system has systemctl --user available, consider using its .timer units instead, as most likely your graphical desktop already forwards the necessary environment variables into your systemd per-user manager.

  • If you don't want to deal with .timer and .service units, you could use systemd-run from crontab to start the script in the correct environment:

    00 20 * * * systemd-run --user ~/Bilder/Hintergründe/.background_skript/background_night.sh 

If you want to do everything through cron:

  1. Run echo $DBUS_SESSION_BUS_ADDRESS in a terminal window and check what path is shown.

  2. If the bus path was shown as /run/user/XXX/bus, its location is static – you can just put one of the following at the top of your cronjob (or, export them at the beginning of your script):

    XDG_RUNTIME_DIR="/run/user/XXX" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/XXX/bus" 

    (Usually XDG_RUNTIME_DIR is enough to cover D-Bus as well as various other components.)

  3. If the bus path is shown as /tmp/dbus-XXXXXXX, it's dynamic – you need to store the value somewhere on every login:

    1. Edit ~/.xprofile or ~/.xinitrc (whichever applies) to store the environment in files:

      echo "$DBUS_SESSION_BUS_ADDRESS" > /tmp/dbus.env echo "$DISPLAY" > /tmp/display.env 
    2. Edit your script to load the environment from files:

      export DBUS_SESSION_BUS_ADDRESS=$(< /tmp/dbus.env) export DISPLAY=$(< /tmp/display.env) 
0

Cron jobs are run by root for all users. That means that some personal shortcuts are not appropriate:

  • $HOME must be replaced by explicit path. ~/ also.
  • The $PATH used by root is not your own customized $PATH. Use complete path for executables.
  • Variables from your environment may not exist in root environment.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.