Automate a fresh Linux wallpaper every day

A Linux wallpaper changer can be as simple as a small script and a scheduler, with no account, paid application or permanent background service. Onlyfreewallpaper fits this lightweight approach: it points visitors towards free wallpaper resources without requiring a subscription, rather than operating as a large paid marketplace. You keep the downloaded images in a folder you control. If your goal is a fresh screen for the arvo, there is no reason to install a heavy app that hides your collection.

A daily rotation sounds simple until you account for dark mode, monitor layouts, missed wake-ups and the differences between GNOME, KDE Plasma, Cinnamon and XFCE. The method below uses commands already present on common Linux desktops, then adapts the image-setting step to each one. It suits a desktop or laptop used at home and at work, and the time can be changed later. Local-time scheduling matters in Australia: an 8 am timer follows daylight-saving changes in Melbourne, Sydney, Hobart and Launceston, while Brisbane keeps a fixed offset.

Choose the method that matches your desktop

Start with your desktop environment rather than the Linux distribution name. Ubuntu may run GNOME, Kubuntu runs Plasma, Linux Mint may run Cinnamon, and Xubuntu usually runs XFCE. The same Linux kernel can therefore need different commands. Choose the option that describes the session you see at login, and avoid installing two wallpaper managers just to test the idea because they can overwrite each other’s settings.

The common choices differ in how they apply an image and what they require:

Desktop or session Method What to expect
GNOME Set picture-uri through gsettings Native light and dark wallpaper settings
KDE Plasma Run plasma-apply-wallpaperimage Uses Plasma’s wallpaper configuration
Cinnamon Use org.cinnamon.desktop.background Native background changes through gsettings
XFCE Update the last-image property with xfconf-query Works across monitor and workspace layouts
X11 fallback Run feh --bg-fill Lightweight, but not intended for native Wayland desktops

You can confirm a session with echo $XDG_CURRENT_DESKTOP; the output often contains GNOME, KDE, Cinnamon or XFCE. If it is blank, check which desktop package you installed instead of guessing. Native tools leave the least room for surprises and make the timer easier to troubleshoot.

Prepare your images and changing script

Create ~/Pictures/Wallpapers and put several JPG, PNG or WebP images inside. Use short file names without spaces so their file URLs stay simple. Choose images close to your screen’s native resolution instead of stretching small pictures. A 1920×1080 laptop suits a 16:9 image, while a 3840×1080 ultrawide display needs a wider ratio. For mixed-resolution setups, keep separate folders for each screen type.

Create ~/.local/bin/change-wallpaper in a text editor and paste this Bash script. It selects images alphabetically and advances one place each local day, wrapping around after the final file.

#!/usr/bin/env bash
set -euo pipefail

folder="$HOME/Pictures/Wallpapers"
shopt -s nullglob
images=("$folder"/*.jpg "$folder"/*.jpeg "$folder"/*.png "$folder"/*.webp)

if ((${#images[@]} == 0)); then
  echo "No images found in $folder" >&2
  exit 0
fi

day_of_year=$(date +%j)
index=$(( (10#$day_of_year - 1) % ${#images[@]} ))
image="${images[$index]}"
uri="file://$image"

apply_gsettings() {
  local schema="$1"
  gsettings set "$schema" picture-uri "$uri"
  gsettings set "$schema" picture-uri-dark "$uri"
}

case "${XDG_CURRENT_DESKTOP:-}" in
  *KDE*|*Plasma*)
    plasma-apply-wallpaperimage "$image" ;;
  *GNOME*|*Unity*)
    apply_gsettings org.gnome.desktop.background ;;
  *Cinnamon*)
    apply_gsettings org.cinnamon.desktop.background ;;
  *XFCE*)
    xfconf-query -c xfce4-desktop -l |
      grep '/last-image$' |
      while IFS= read -r property; do
        xfconf-query -c xfce4-desktop -p "$property" -s "$image"
      done
  *)
    if gsettings writable org.gnome.desktop.background picture-uri >/dev/null 2>&1; then
      apply_gsettings org.gnome.desktop.background
    elif gsettings writable org.cinnamon.desktop.background picture-uri >/dev/null 2>&1; then
      apply_gsettings org.cinnamon.desktop.background
    elif command -v feh >/dev/null 2>&1; then
      feh --bg-fill "$image"
    else
      echo "No wallpaper command found for this desktop" >&2
      exit 1
    fi ;;
esac

The picture-uri key tells GNOME or Cinnamon which file to display, and picture-uri-dark keeps the image in a dark theme. Plasma receives the path through its dedicated command. XFCE stores the last image under a property whose name depends on the monitor and workspace, so the script finds it rather than guessing. The feh branch is a fallback for X11 sessions.

Make the script executable with chmod +x ~/.local/bin/change-wallpaper, then run it once. If nothing changes, check echo $XDG_CURRENT_DESKTOP and command -v feh to identify the available route. Install feh with sudo apt install feh, sudo dnf install feh or sudo pacman -S feh if you need that fallback. Test before scheduling so any path or permission problem stays easy to fix.

Schedule the change with a user timer

Run the script manually, then let systemd handle the timing. A user timer belongs to your account, needs no root privileges and is already available on mainstream distributions. It also avoids a common cron problem: a background job can start before the graphical session and fail to reach the desktop settings.

Create ~/.config/systemd/user/wallpaper-change.service with these contents:

[Unit]
Description=Change the desktop wallpaper
After=graphical-session.target

[Service]
Type=oneshot
ExecStart=%h/.local/bin/change-wallpaper

The ExecStart line uses %h for your home directory, avoiding a hard-coded username. The service changes one wallpaper and exits; the timer decides when to start it.

Next, create ~/.config/systemd/user/wallpaper-change.timer:

[Unit]
Description=Change the desktop wallpaper daily

[Timer]
OnCalendar=*-*-* 08:00:00
Persistent=true
RandomizedDelaySec=20min
Unit=wallpaper-change.service

[Install]
WantedBy=timers.target

Persistent=true catches a missed run after the computer was off, while RandomizedDelaySec=20min allows a short delay before the change. Everything happens locally, without a remote wallpaper service.

Reload the user manager and enable the timer:

systemctl --user daemon-reload
systemctl --user enable --now wallpaper-change.timer
systemctl --user list-timers wallpaper-change.timer

The last command shows the next run. To test immediately, use systemctl --user start wallpaper-change.service; inspect problems with journalctl --user -u wallpaper-change.service -n 30. The schedule uses local time, so daylight-saving changes do not turn your chosen start into another hour.

Keep downloads and screen choices organised

A wallpaper changer cannot repair a poorly matched image. Compare each picture’s resolution and aspect ratio with the displays you use. A 16:9 file generally suits a standard laptop, while a 21:9 image suits an ultrawide monitor. Vertical phone photos can look awkward on a landscape desktop, so crop them or choose another image. Set GNOME’s background scaling to Zoom, or use your desktop’s own fitting controls, when the default crop is not right.

Keep separate folders for work, travel and personal images, then copy or link selected files into the active wallpaper folder. A symlink avoids duplicating large files: ln -s ~/Pictures/Nature/blue-mountains.jpg ~/Pictures/Wallpapers/ makes a selectable link. Avoid filling the folder with every download, because duplicates and mismatched sizes become harder to spot.

Keep wallpaper resources on a separate bookmarks list, and check each image’s stated licence before using it. Free wallpaper pages often point to third-party downloads rather than selling usage rights, so a free download does not automatically grant every commercial-use, editing or redistribution right. This matters when a home office doubles as a small creative studio and a client presentation appears on the same laptop. Keep attribution details and source URLs in a plain text file beside the collection, even when a credit is not required.

Phones run Linux through Android, but Android does not offer the same desktop automation path. A background-changing app may work if the phone permits it, yet battery optimisation and vendor skins can interrupt scheduled changes. A daily Linux setup usually belongs on the computer; leave phone rotation to the mobile platform’s wallpaper controls. To use one picture everywhere, save a favourite in your shared photo library and let each device apply its own crop.

Make the routine reliable

Run the script manually before trusting the timer. The day-of-year calculation makes the sequence change at local midnight and wrap after the final image. If you prefer random pictures, replace the index line with index=$((RANDOM % ${#images[@]})), accepting that the same image can occasionally appear twice in succession.

If the timer appears but the wallpaper never changes, check systemctl --user status wallpaper-change.timer and journalctl --user -u wallpaper-change.service -n 30. A permission error usually means the script is not executable; chmod +x ~/.local/bin/change-wallpaper fixes it. “No images found” means the folder is empty or its path differs from the script. On Wayland, feh often cannot set the background, so use the native desktop command.

Keep the wallpaper folder inside your home directory so it survives a reboot and is easy to back up. A syncing service can copy it to another computer, but avoid live system configuration on services that rewrite files aggressively. Test after a normal restart, then test once after the computer has been off at the scheduled time. The persistent option should run the missed change once the graphical session starts.

Start with five images you genuinely like, save the script, and run the timer once today. Choose a time that suits your routine, such as the start of the working day or an afternoon refresh. Visit Onlyfreewallpaper for new wallpaper ideas, then let the scheduler handle tomorrow.