Reputation: 3742
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
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
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
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
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
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
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
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
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