xralf
xralf

Reputation: 3742

Shell script changing desktop wallpaper

Could you write the easiest possible shell script that will change the desktop wallpaper (in Ubuntu) in regular intervals (e.g. 1 minute).

Wallpapers will be saved in particular directory (e.g. $HOME/wallpapers). I need only basic functionality.

1) select random wallpaper from $HOME/wallpapers
2) set it as wallpaper on desktop
3) set cron to run the script every minute (not part of the question).

Upvotes: 12

Views: 34254

Answers (8)

kpapdx
kpapdx

Reputation: 11

This is far from simple, but it works well for me. You can also find it on github: kendalla59/wallup

#!/bin/bash
#
# wallup
#   Update wallpaper images on a timed basis.

# This directory contains images to use as desktop wallpaper.
DEFAULT_WPHOME="$HOME/Pictures/Wallpaper"

# Any files with the following file extensions will be used.
WPEXTS=(jpg png gif jpeg JPG)

# This is the interval between wallpaper image updates, in seconds.
WPTIME=$((10 * 60))

# This is the name of the subdirectory to place the images
# that have been previously selected at random for wallpaper.
WPSAVE=.wpsave

# This variable enables two images to be used side-by-side for
# a dual monitor configuration.
#WPDUAL=false
WPDUAL=true

WPCVTS=0

# Prior to running this script, set the WPHOME environment
# variable to set a non-default wallpaper folder.
if [[ -z "$WPHOME" ]]; then
    if [[ -d "$DEFAULT_WPHOME" ]];  then WPHOME=$DEFAULT_WPHOME
    elif [[ -d "$HOME/Pictures" ]]; then WPHOME=$HOME/Pictures
    else                                 WPHOME=$HOME
    fi
fi

WPDEST="$WPHOME"/"$WPSAVE"
if [[ ! -d "$WPDEST" ]]; then
    mkdir "$WPDEST"
    if [[ $? != 0 ]]; then
        echo "Unable to create $WPDEST. Exiting..."
        exit
    fi
fi

function getdate {
    printf -v WPDATE '%-5d %s %s' $$ $(date +"%D %I:%M%p")
}
getdate

WPHIST="$WPDEST"/wallup.log
WPLOCK="$WPDEST"/.mult-lock
WPLPID="$WPLOCK"/lock-$$

echo "$WPDATE  Starting wallpaper updater for user $USER." >> "$WPHIST"

# Check if we can merge two images for the background.
if $WPDUAL; then
    hash convert >& /dev/null
    if [[ $? -ne 0 ]]; then
        WPDUAL=false
        echo "$WPDATE  Install \"imagemagick\" for dual displays." >> "$WPHIST"
        echo "$WPDATE  ->  (sudo apt install imagemagick)" >> "$WPHIST"
    fi
fi

# If an old lock file exists, clear it out now.
if [[ -d "$WPLOCK" ]]; then
    for oldfile in "$WPLOCK"/*; do
        if [[ -f "$oldfile" ]]; then
            echo "$WPDATE  Removing old lock \"$oldfile\"." >> "$WPHIST"
            rm "$oldfile"
        fi
    done
else
    mkdir "$WPLOCK"
fi

# Create a new lock file for this process ID
touch "$WPLPID"

function getnext {

    # Randomly select the next wallpaper image(s).
    cd "$WPHOME"
    WPNEXT=$(ls ${WPEXTS[@]/#/"*."} 2> /dev/null | shuf -n 1)

    # If no image was found, reload images from the saved folder.
    if [[ "$WPNEXT" == "" ]]; then
        cd "$WPDEST"
        WPFCNT=$(ls -1 ${WPEXTS[@]/#/"*."} 2> /dev/null | wc -l)
        echo "$WPDATE  Moving $WPFCNT image files from $WPSAVE back up to $WPHOME." >> "$WPHIST"
        mv ${WPEXTS[@]/#/"*."} "$WPHOME" 2> /dev/null

        # Now get a random wallpaper image.
        cd "$WPHOME"
        rm cvt-*.png
        WPCVTS=0
        WPNEXT=$(ls ${WPEXTS[@]/#/"*."} 2> /dev/null | shuf -n 1)

        # Quit now if there are no images in the wallpaper folder.
        if [[ "$WPNEXT" == "" ]]; then
            echo "$WPDATE  No Wallpaper images found in $WPHOME. Exiting..." >> "$WPHIST"
            rm -f "$WPLPID"
            exit
        fi
    fi

    # If the destination directory has disappeared, exit now.
    if [[ ! -d "$WPDEST" ]]; then
        echo "No directory $WPDEST. Exiting..."
        exit
    fi
}

while true; do

    # Responsiveness to logout or multiple instances is determined
    # by the WPRESP variable, the time to respond in seconds.
    WPWAIT=$WPTIME
    WPRESP=10

    while [[ $WPWAIT -gt 0 ]]; do
        if [[ ! -f "$WPLPID" ]]; then
            getdate
            echo "$WPDATE  Missing \"$WPLPID\". Exiting..." >> "$WPHIST"
            exit
        fi

        sleep $WPRESP
        WPWAIT=$((WPWAIT - WPRESP))

        if [[ $(ps -C gnome-shell -o euser= | grep $USER) == "" ]]; then
            getdate
            echo "$WPDATE  User $USER not logged in. Exiting..." >> "$WPHIST"
            rm -f "$WPLPID"
            exit
        fi
    done
    getdate

    ((WPCVTS+=1))
    WPFILE="$WPDEST"/cvt-$WPCVTS.png

    getnext
    if $WPDUAL; then
        WPNEXT1=$WPNEXT
        mv "$WPHOME"/"$WPNEXT1" "$WPHOME"/"$WPNEXT1".HOLD
        getnext
        WPNEXT2=$WPNEXT
        mv "$WPHOME"/"$WPNEXT1".HOLD "$WPDEST"/"$WPNEXT1"
        mv "$WPHOME"/"$WPNEXT2" "$WPDEST"

        # Create the merged background image.
        cd "$WPDEST"
        convert "$WPNEXT1" "$WPNEXT2" +append "$WPFILE"
        echo "$WPDATE  New wallpaper file://$WPFILE (from $WPNEXT1 + $WPNEXT2)" >> "$WPHIST"
    else
        mv "$WPHOME"/"$WPNEXT" "$WPDEST"
        WPFILE="$WPDEST"/"$WPNEXT"
        echo "$WPDATE  New wallpaper file://$WPFILE" >> "$WPHIST"
    fi

    gsettings set org.gnome.desktop.background picture-uri file://"$WPFILE"

done

Upvotes: 1

toddmo
toddmo

Reputation: 22436

Unfortunately, the random function alone doesn't cut it.

It can pick the same file again. this is annoying.

You'll need something like this

  shuffle(items: string[]) {
    console.log('shuffling...')
    this.items = items.reduce(
      ([original, shuffled]) =>
        [original, [...shuffled, ...original.splice(Math.random() * original.length | 0, 1)]],
      [[...items], []]
    )[1]
    this.cursor = undefined
    return this.items
  }

I just launched a free random wallpaper app that does this.

Upvotes: 0

Indrajith Indraprastham
Indrajith Indraprastham

Reputation: 1348

This worked for me in Gnome:

#!/bin/bash

DIR="/home/user/Pictures/wallpapers"
PIC=$(find $DIR -type f -maxdepth 1 | shuf -n1)
gsettings set org.gnome.desktop.background picture-uri "file://$PIC"

Upvotes: 1

tomeu_quely
tomeu_quely

Reputation: 61

For gnome3 you need to use gsettings instead of gconftool.

But if you're going to execute the script throught cron it will not work.

I've tried a lot of .sh scripts but no one works for me.

At the end, i fixed it using this python script that loads a random wallpaper from a folder:

#!/usr/bin/env python
#coding: utf8 

import os,random
setup = "/path_to_folder/" + random.choice(os.listdir("/path_to_folder/"))
os.system("DISPLAY=:0 GSETTINGS_BACKEND=dconf gsettings set org.gnome.desktop.background picture-uri  'file://%s'" %(setup))

Hope it helps for someone with my same problem!

Upvotes: 2

mackatozis
mackatozis

Reputation: 252

This is just my approach on this matter. I don't claim that it's the ideal one.

WALLS_PATH=/path/to/images
cd $WALLS_PATH

while [ 1 ]; do
    for NEW_WALL in "$WALLS_PATH"/*; do
        gsettings set org.gnome.desktop.background picture-uri "file://${NEW_WALL}"
        sleep 1800
    done
done

Upvotes: 3

Migwel
Migwel

Reputation: 143

I know this answer is kind of late but since it could help some people, I'm posting it.

From septi's code plus some modifications, here is my solution :

#!/bin/bash
wallpaperdir="$HOME/wallpaper"

files=($wallpaperdir/*)
randompic=`printf "%s\n" "${files[RANDOM % ${#files[@]}]}"`

echo -e "# xfce backdrop list\n$randompic">$HOME/.config/xfce4/desktop/backdrop.list
xfdesktop --reload

The single quotes must be replaced by double quotes in order for the computer to interpret the $HOME part correctly. Also, the file you want to edit is backdrop.list, not backdrops.list. And finally, I find that using killall is kind of excessive in this case, since you can simply reload xfdesktop.

I've tested it on my computer (Linux Mint Debian Edition) and it seems to work perfectly.

Hope it helps. =)

EDIT : I forgot to mention that you have to add DISPLAY=:0.0 before your command, in crontab. That gives

*/1 * * * * DISPLAY=:0.0 wallpaper.sh

Upvotes: 4

Jabba
Jabba

Reputation: 20644

Try this in newer Ubuntus: gsettings set org.gnome.desktop.background picture-uri file:///path/to/img.jpg (tip from here)

Upvotes: 2

tamasgal
tamasgal

Reputation: 26319

#!/bin/bash
wallpaperdir='$HOME/wallpaper'

files=($wallpaperdir/*)
randompic=`printf "%s\n" "${files[RANDOM % ${#files[@]}]}"`

gconftool-2 -t str --set /desktop/gnome/background/picture_filename "$randompic"

Save this script and edit your with the command "crontab -e" (it launches an editor where you put this line at the end of the file):

*/1     *     *     *     *         /bin/bash /path/to/script.sh

edit: I assumed you're using gnome. If not you need to edit the last line, because my example uses the Gnome Conftool. ;)

To change the background in XFCE, you should change the line with gconftool-2 to:

echo -e “# xfce backdrop list\n$randompic”>$HOME/.config/xfce4/desktop/backdrops.list    
killall -USR1 xfdesktop

Upvotes: 15

Related Questions