Shell script changing desktop wallpaper
Asked Answered
M

8

12

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).

Minuscule answered 5/4, 2011 at 11:13 Comment(3)
Maybe this should be asked on askubuntu.com?Chronogram
Here are 5259 questions tagged bash. On askubuntu only 144. The question is about programming. Ubuntu is more about desktop environment.Minuscule
Basically the answer to this depends on your desktop environment / window-manager. Everyone in this question, incl. OP seems to use Gnome, so the gnome-tools using answer works. For future visitors using KDE / XFCE / LXDE / MATE / others, ask your DE how it programmatically sets its wallpaper.Smatter
S
15
#!/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
Snath answered 5/4, 2011 at 11:29 Comment(8)
Thank you. I'm using gnome and xfce. Would you know how to change it in XFCE too?Minuscule
I used #!/bin/bash<br> files=(/home/xralf/wallpapers/*)<br> randompic=printf "%s\n" "${files[RANDOM % ${#files[@]}]}"<br> cp "$randompic" desktop_picture.jpg<br> cp desktop_picture.jpg /usr/share/xfce4/backdrops<br> killall xfdesktop<br> xfdesktop but it doesn't work as expected.Minuscule
I edited my first answer, because the comment function is not very useful for posting code ;-)Snath
This doesn't work. May I send you the file somewhere? If there is not mistake?Minuscule
You have to look at $HOME/.config/xfce4/desktop/backdrops.list, it should exist and after executing the last command, there should be a new entry. But you can paste the file on pastebin or something like that, we will solve this problem ;-)Snath
Sorry I missed your comment. Here is the pastebin link.Minuscule
Why not just gconftool-2 -t str --set /desktop/gnome/background/picture_filename "${files[RANDOM % ${#files[@]}]}" and get rid of a useless variable randompic and of a subshell and ugly syntax?Hypesthesia
It's not working for me. Please give more details. I'm running the latest version of Ubuntu 18.04.1 LTS x86_64 Desktop version.Mycobacterium
T
4

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
Transatlantic answered 20/8, 2012 at 21:23 Comment(0)
B
3

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
Bikaner answered 26/12, 2012 at 16:3 Comment(0)
P
2

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

Photoelasticity answered 5/4, 2012 at 21:25 Comment(0)
E
2

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!

Elephant answered 28/5, 2014 at 21:44 Comment(0)
B
1

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"
Bedder answered 12/8, 2014 at 6:57 Comment(1)
One short note though: do not rely on/parse ls results, find is more suitable.Biggerstaff
B
1

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
Bifarious answered 23/5, 2023 at 22:20 Comment(0)
T
0

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.

Tuinenga answered 15/2, 2023 at 22:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.