Running .sh every 5 minutes

Put it in your crontab.

Open your cron table by:

crontab -e

Now add:

*/5 * * * * /path/to/script.sh

Don't forget to make the script executable beforehand.


As your script depends on X, probably will be a good idea to add the DISPLAY to the script's environment:

*/5 * * * * DISPLAY=:0 /path/to/script.sh

Replace :0 with your actual DISPLAY (can be found by echo $DISPLAY from interactive session).

If needed, you can add the XAUTHORITY environment variable too:

*/5 * * * * DISPLAY=:0 XAUTHORITY="~/.Xauthority" /path/to/script.sh

Again you can find the value by echo $XAUTHORITY.


The lazy option

If you want the easy way, and avoid having to find out which environment variable to set:

  • Make sure your script includes the shebang
  • Make it executable
  • Add the following to Startup Applications:

    /bin/bash -c "sleep 15 && while true; do <path_to_your_script.sh> ; sleep 300; done"
    

    Dash > Startup Applications > Add. Add the command:

    /bin/bash -c "sleep 15 && while true; do <path_to_your_script.sh> ; sleep 300; done"
    

Explanation

If you run the script from your own environment (e.g. from a terminal window or from Startup Applications), a number of environment variables will be set. cron however runs your script with a limited set of environment variables.
Since your script no doubt uses the gsettings command:

gsettings get org.gnome.desktop.background picture-uri <wallpaper>

to set the wallpaper, almost certainly the command will break when run from cron.

The downside of "the lazy solution" is purely theoretical. A command that sleeps practically continuously means nothing to your system.

Additional info; alternatively

Reading this post, and from experiences in the past, I am pretty sure the DBUS_SESSION_BUS_ADDRESS environment variable needs to be set.

To do so, add the following section at the beginning of your script (below the shebang):

PID=$(pgrep gnome-session)
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-)

Then you should be able to successfully run it from cron.

You could however very well save the hustle, and choose the lazy option.