One of the things I like about macOS is the ability to set a directory of images as my desktop background and have the system choose images at random every so many minutes. Unfortunately, Ubuntu 22.04 and earlier versions lack this ability.
Luckily, we can solve this problem with a ten line Bash script and a one line addition to our crontab.
First, create a ~/bin directory in your home directory, if you don’t already have one. Inside it, create the following script (background.sh):
#!/bin/bash
USER=`id -un`
UID=`id -u`
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus
GNOME_SHELL=`ps --user=$USER | grep gnome-shell$`
if [ ! -z "$GNOME_SHELL" ] ; then
PICDIR=~/Backgrounds
CURPIC=`ls $PICDIR | egrep -i "(png|jpg|jpeg)$" | shuf -n 1`
gsettings set org.gnome.desktop.background picture-uri $PICDIR/$CURPIC
fi
Next, make the script executable. Type the following into a Terminal.
chmod ugo+x ~/bin/background.sh
Next, create a directory in your home directory called Backgrounds and put some images in there that you’d like to display as your Gnome desktop background. For the purposes of this project, try to put in at least three images or more.
At this point you can change your background any time you want by typing
~/bin/background.sh
into a Terminal. Now let’s make the script run automatically as often as you’d like. Use the following command in Terminal to edit your crontab:
crontab -e
Add the following line to the bottom of the file, followed by the blank line. This will change the image every minute. Change travis (which is the name of my home directory) to the name of your home directory.
* * * * * /home/travis/bin/background.sh
To change the image every 2 minutes use this line instead in your crontab:
*/2 * * * * /home/travis/bin/background.sh
For every 5 minutes use this line instead:
*/5 * * * * /home/travis/bin/background.sh
Now your Gnome desktop background image should automatically change every so often to a random image from your Backgrounds directory. To turn off the automatic changes, use
$ crontab -e
and comment out the last line by putting a # character in front of it.
# */2 * * * * /home/travis/bin/background.sh
When you take out all the explanations, setting up this project was really just a matter of creating a directory of images, creating a ten line script, and adding one line to your crontab file. Now your Ubuntu desktop can have randomly changing backgrounds just like macOS.
How Does It Work?
Let’s look at the script in more detail. The core of it is the following 3 lines.
PICDIR=~/Backgrounds
CURPIC=`ls $PICDIR | egrep -i "(png|jpg|jpeg)$" | shuf -n 1`
gsettings set org.gnome.desktop.background picture-uri $PICDIR/$CURPIC
In the first line, we set the variable PICDIR to the directory that holds our pictures. In the second line, we choose a random filename from PICDIR.
The shuf command displays a random line from a file (or stdin). For example, you can try
$ ls | shuf -n 1
to display a random filename from the current directory. Let’s make things a bit more complex:
ls ~/Backgrounds | egrep -i "(png|jpg|jpeg)$" | shuf -n 1
This command returns a random image filename from the user’s Backgrounds directory.
- First, the
ls ~/Backgroundscommand makes a list of files in the directory, one file per line. - Then with the pipe character
|we feed the output oflsintoegrep. egrep -i "(png|jpg|jpeg)$"looks for lines that end with "png", "jpg", or "jpeg".- The
-iin the middle says to do a case insensitive search, soegrepwill find "png", "PNG", "jpg", "JPG", etc. - Then we take the list of image files
egrepproduces, and with another pipe|we pass it toshuf. shuf -n -1takes one line at random from the input it is given and returns it.
You can run the command line above in the Terminal, and each time you do you should get a random filename from the Backgrounds directory.
Now that we can get random file names from a directory, let’s actually change the desktop background.
You can set the desktop background image using the gsettings command. For example, if we have an image called Fred.jpg that we’d like to make the background, we’d type the following in the Terminal:
gsettings set org.gnome.desktop.background picture-uri /home/travis/Backgrounds/Fred.jpg
If you want to set the background to no image, use
gsettings set org.gnome.desktop.background picture-uri ''
At this point, our script could look like this:
#!/bin/bash
UID=`id -u`
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus
PICDIR=~/Backgrounds
CURPIC=`ls $PICDIR | egrep -i "(png|jpg|jpeg)$" | shuf -n 1`
gsettings set org.gnome.desktop.background picture-uri $PICDIR/$CURPIC
We need to put the
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus
in the script in order to give it access to the Gnome environment when it runs. If we ever run the script from an SSH shell or from crontab we’d get an error without this line.
Now there is one last issue. Cron jobs run whether you are logged in or not. They run whether Gnome is running or not. This fact means that right now your desktop background is going to keep changing even if you’re not logged into Gnome. That’s a waste of system resources as the cron job tries to change your non-existent desktop.
Luckily, we can find out if you’re logged into Gnome or not with a command like this:
ps --user=travis | grep gnome-shell$
ps --user=travis makes a list of all the processes assigned to the userid travis. We then use the pipe | to feed that into grep to match only the lines that end with gnome-shell. The $ at the end of the pattern matches the end of the line. So specifically, we’re looking to see if you’re running a process called gnome-shell. If you are, you’re running Gnome.
We can now modify our background.sh script to only change the background if Gnome is running.
#!/bin/bash
USER=`id -un`
UID=`id -u`
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus
GNOME_SHELL=`ps --user=$USER | grep gnome-shell$`
if [ ! -z "$GNOME_SHELL" ] ; then
PICDIR=~/Backgrounds
CURPIC=`ls $PICDIR | egrep -i "(png|jpg|jpeg)$" | shuf -n 1`
gsettings set org.gnome.desktop.background picture-uri $PICDIR/$CURPIC
fi
Now on line 5 we put the output from the ps command into the variable GNOME_SHELL if Gnome is running, the output will be empty. On line 4 we use an if statement to say that if (and only if) our variable is not empty, execute lines 5 to 7. Line 8 indicates where our if statement ends.
Like I said above, when you take out all the explanations, setting up this project was really just a matter of creating a directory of images, creating a ten line script, and adding one line to your crontab file. Now your Ubuntu desktop can have randomly changing backgrounds just like macOS.
Categories: Linux
Leave a comment