So, happy 1999 everyone (
date +%y%-m%-d)! I’ve been looking forward to posting an article on this day since last week and after some thinking, decided on a topic. I’ll cover some of the thought processes and resources that went in to my latest script: wpchg.
This script came about while studying for my RHCSA certificate. If you happened to leave your computer unlocked, you were likely to return to a changed desktop background. Time was limited when a) trying to find a wallpaper b) subsequently setting the wallpaper – therefore I wanted to see if I am able to automate the process with a shell script.
With RedHat Enterprise Linux 7, our desktop environment is managed by Gnome, therefore I set out to research a way to change the desktop background via the CLI. It didn’t take long before I found this article on Ask Ubuntu.
The link was very useful in getting the syntax for using the CLI with
gsettings to achieve this. I started experimenting with using different file names, having image extensions (.jpg, .png, etc) with the image and seeing if I could change the path of the image from the home directory of the user to say
From these initial tests I was able to figure out that the image didn’t need an extension, however it needed to be within the home directory of the user, else it wouldn’t set as a background.
My initial idea was to write a script, which would be a few lines, using
gsettings, I would download an image and set it. But this still meant I would have to download the script from a source, ensure that it was executable and run it. The script could then delete itself. Stack Overflow came to the rescue with an article that covered a self deleting script.
Now that the bare bones of the script were done, I began to think what else could I do to elevate the script and improve my scripting skills at the same time. I decided I would add a check to the script, that would ensure the image was still set as a background. While working on another script, I had plenty of experience using loops and if statements to check if files existed and utilizing
I wanted to implement my knowledge of these into the script and set about using an infinite while loop, that would run in the background, constantly checking if certain conditions are met.
The conditions I wanted to check for were a) whether a
crontab was present to set the background at a certain time b) whether the file that will run the
gsettings command is present.
I began experimenting with the while loop until I got it working the way I had wanted it to. After some changes with using variables, file names, settings for
sleep, I managed to run it in the background with it working away for five days without a hitch.
I decided on using here documents in order to create the additional scripts that will run in the background. After some more digging I figured out how I could execute the scripts the main script created from within the script. The here document took some experimentation in getting variables to copy over, but a quick search found the solution – the variables had to be escaped, otherwise they would be expanded when being copied.
The final bit I wanted it achieve was for the script to clean up after itself, removing the last few lines of the
.bash_history file, so as to reduce the likelihood of detection. I achieved this by closing the terminal session to commit the temporary history to the file, and using the
head command to pipe the filtered section to a temp file and overwrite the original.
The script would then remove any additional log files and delete itself. To achieve the ability for it to keep running even after the terminal session was closed, I utilized
Edit: after coming in this morning with the script running all night, I was expecting my desktop background to have been changed. However, this was not the case and I began troubleshooting. The first thing I checked was
/var/mail/user which gave me my first clue:
Date: Tue, 10 Sep 2019 02:00:01 -0500 (CDT)
/bin/sh: ./tmp/.uwpc.bak: No such file or directory
I noticed that I have made a typo in the script, adding a period before the file path. This meant the location could not be executed. I edited the
crontab to remove that and altered the time to run every minute but again no change. I went back to
/var/mail/user to see what was happening now. I was getting the following error message now:
(process:29203): dconf-WARNING **: 08:41:01.857: failed to commit changes to dconf: Cannot autolaunch D-Bus without X11 $DISPLAY
This told me immediately that there was an issue with
X11, which is the X Window System. I copy and pasted that error message to Google and after some searching around I found the issue. When I was running the
gsettings command from within a Terminal, the Terminal loads a variety of environment variables. which are not loaded in
cron as it is a system process.
I began searching for a solution for this, which landed me on Stack Overflow again – that was extremely helpful in identifying the issue and providing a solution. After editing the shell script to be run, I went back to the
crontab to test it out again. This time, it work! My desktop background changed. This is something that I will have to fix on GitHub for the script.
Summary of skills I’ve learnt while writing this script:
- Troubleshooting – checking different functions of a script, checking log files, output and debugging issues
- Researching – reading manpages and utilizing web resources to gather information and examples
- Using here documents to create scripts from within a script
- Using gsetting to alter Gnome from the CLI
- Working with variables when using the here document and redirecting output of applications
- Improved commenting within the shell script along with documenting through process along the way
- Utilizing nohup to allow for a script to run in the background even after a terminal session is terminated
- Version control via GitHub
- Improved utilization and troubleshooting of crontab
- File processing using head and piping / moving results to save edits