Gsettings с cron

Я написал скрипт bash, который меняет обои (для GNOME3).

#!/bin/bash

# Wallpaper's directory.
dir="${HOME}/images/wallpapers/"

# Random wallpaper.
wallpaper=`find "${dir}" -type f | shuf -n1`

# Change wallpaper.
# http://bit.ly/HYEU9H
gsettings set org.gnome.desktop.background picture-options "spanned"
gsettings set org.gnome.desktop.background picture-uri "file://${wallpaper}"

Скрипт, выполненный в эмуляторе терминала (например, gnome-terminal), отлично работает. Во время выполнения cron или терминала ttyX возникает ошибка:

** (process:26717): WARNING **: Command line `dbus-launch --autolaunch=d64a757758b286540cc0858400000603 --binary-syntax --close-stderr' exited with non-zero exit status 1: Autolaunch error: X11 initialization failed.\n

** (process:26717): WARNING **: Command line `dbus-launch --autolaunch=d64a757758b286540cc0858400000603 --binary-syntax --close-stderr' exited with non-zero exit status 1: Autolaunch error: X11 initialization failed.\n

** (process:26721): WARNING **: Command line `dbus-launch --autolaunch=d64a757758b286540cc0858400000603 --binary-syntax --close-stderr' exited with non-zero exit status 1: Autolaunch error: X11 initialization failed.\n

** (process:26721): WARNING **: Command line `dbus-launch --autolaunch=d64a757758b286540cc0858400000603 --binary-syntax --close-stderr' exited with non-zero exit status 1: Autolaunch error: X11 initialization failed.\n

person Mateusz Jagiełło    schedule 29.04.2012    source источник
comment
Ни одно из решений не сработало для меня. :( Мне пришлось установить DISPLAY=:0.0 перед командой в выражении cron. (ubuntuforums.org/ showthread.php?t=1023215). P.S. Я пытаюсь запустить скрипт Python, использующий pynotify.   -  person Hussain    schedule 01.02.2015
comment
@Hussain: Прошло некоторое время с тех пор, как я задал вопрос. Бьюсь об заклад, что ответ ниже моего должен быть лучше - просто прочитайте все обсуждение.   -  person Mateusz Jagiełło    schedule 01.02.2015


Ответы (7)


Наконец мне удалось решить эту проблему после многих, многих попыток.

Действительно, проблема возникает из-за того, что cron использует очень ограниченный набор переменных окружения. И единственная переменная среды, которая отвечает за правильный запуск сценария из вопроса, когда он установлен как задание cron, — это DBUS_SESSION_BUS_ADDRESS, а не DISPLAY или XAUTHORITY или GSETTINGS_BACKEND или что-то еще. Этот факт также был хорошо отмечен в этом ответе.

Но проблема в этом ответе заключается в том, что нет гарантии, что переменная DBUS_SESSION_BUS_ADDRESS из этого файла из Каталог ~/.dbus/session-bus/ обновляется до текущего значения из текущего сеанса gnome. Чтобы решить эту проблему, можно найти PID процесса в текущем сеансе gnome и получить адрес dbus из его среды. Мы можем сделать это следующим образом:

PID=$(pgrep gnome-session)  # instead of 'gnome-session' it can be also used 'noutilus' or 'compiz' or the name of a process of a graphical program about that you are sure that is running after you log in the X session
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-)

При этом скрипт должен выглядеть так:

#!/bin/bash

# TODO: At night only dark wallpapers.

# Wallpaper's directory.
dir="${HOME}/images/wallpapers/"

# export DBUS_SESSION_BUS_ADDRESS environment variable
PID=$(pgrep gnome-session)
export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ|cut -d= -f2-)

# Random wallpaper.
wallpaper=`find "${dir}" -type f | shuf -n1`

# Change wallpaper.
# http://bit.ly/HYEU9H
gsettings set org.gnome.desktop.background picture-options "spanned"
gsettings set org.gnome.desktop.background picture-uri "file://${wallpaper}"
person Radu Rădeanu    schedule 29.10.2013
comment
Большое спасибо. У меня есть скрипт, который обновляет обои на рабочем столе в полночь. Этот скрипт перестал корректно работать несколько месяцев назад. Когда я запускал его в обычном режиме, он работал, но из crontab он не работал. С помощью этого трюка я смог решить проблему. - person Jabba; 06.02.2014
comment
Для двухэкранных мониторов измените параметр spanned на zoom. - person n0p; 22.10.2014
comment
Спасибо за это решение. Мне пришлось немного изменить его для работы с gnome-shell в Debian: PID=$(pgrep -o gnome-shell). - person scai; 05.07.2015
comment
Это правильный ответ для Ubuntu 15.04. У меня включен зашифрованный домашний каталог, поэтому, когда я пытаюсь запустить скрипт из tty02, мне будет предложено ввести пароль в Unity, но при запуске из cron фон меняется без проблем. - person eurythmia; 29.09.2015
comment
чтобы запустить приложение X, вы должны добавить env DISPLAY=:0.0 впереди. Кроме того, он отлично работает. Большое спасибо! - person Mat; 01.10.2015
comment
Что происходит, когда gnome-session не работает? - person joshreesjones; 14.12.2015
comment
Что делать, если более одного пользователя вошли в систему? Тогда pgrep вернет более одного значения - person In78; 29.03.2016

Я нашел некоторые решения. Когда вы экспортируете переменную DBUS_SESSION_BUS_ADDRESS, содержащуюся в файле ~/.dbus/session-bus/*, dbus-launch больше не сообщает об ошибке. Однако вместо обоев — артефакты.

Добавлен код:

sessionfile=`find "${HOME}/.dbus/session-bus/" -type f`
export `grep "DBUS_SESSION_BUS_ADDRESS" "${sessionfile}" | sed '/^#/d'`

Теперь скрипт выглядит так:

#!/bin/bash

# TODO: At night only dark wallpapers.

# Wallpaper's directory.
dir="${HOME}/images/wallpapers/"

# Weird, but necessary thing to run with cron.
sessionfile=`find "${HOME}/.dbus/session-bus/" -type f`
export `grep "DBUS_SESSION_BUS_ADDRESS" "${sessionfile}" | sed '/^#/d'`

# Random wallpaper.
wallpaper=`find "${dir}" -type f | shuf -n1`

# Change wallpaper.
# https://superuser.com/questions/298050/periodically-changing-wallpaper-under-gnome-3/298182#298182
gsettings set org.gnome.desktop.background picture-options "spanned"
gsettings set org.gnome.desktop.background picture-uri "file://${wallpaper}"
person Mateusz Jagiełło    schedule 30.04.2012

Попробовал это, и это отлично сработало для меня:

dbus-launch --exit-with-session gsettings set schema key value

Или из корневого cron:

sudo -u user dbus-launch --exit-with-session gsettings set schema key value

Источник: http://php.mandelson.org/wp2/?p=565

person Arnon Weinberg    schedule 21.12.2012
comment
С этим возникает проблема, если вы используете его в интерактивном сеансе (например, ssh), а в системе запущен отдельный сеанс X11; это, кажется, вызывает какое-то замедление или, возможно, захват нажатия клавиш, пока ваш сеанс не закончится. Страница руководства для dbus версии 1.8.18 гласит: Чтобы запустить сеанс D-Bus в рамках сеанса text\(hymode, не используйте dbus-launch. Вместо этого см. **dbus-run-session**(1). ( Я думаю, что странная вещь \( — это ошибка форматирования.) К сожалению, похоже, что dbus-run-session довольно новый, так как он есть в Debian 8, но не в Debian 7. - person Kyle Strand; 01.09.2016

Чтобы изменить обои через cron, просто сделайте это прямо в своем crontab: Выполните crontab -e

Добавьте такие строки:

30 09 * * * DISPLAY=:0 GSETTINGS_BACKEND=dconf /usr/bin/gsettings set org.gnome.desktop.background picture-uri file:////home/elison/Pictures/morning.jpg

00 12 * * * DISPLAY=:0 GSETTINGS_BACKEND=dconf /usr/bin/gsettings set org.gnome.desktop.background picture-uri file:////home/elison/Pictures/noon.jpg

person Elison Niven    schedule 07.09.2012

add export DISPLAY=:0 && export XAUTHORITY=/home/username/.Xauthority , где username — это ваше имя пользователя Ubuntu. Это должно исправить ошибку авторизации X11.

person Vivek Pradhan    schedule 02.01.2013

Также посмотрите это решение, которое работает для меня: https://unix.stackexchange.com/questions/111188/using-notify-send-with-cron#answer-111190 :

Вам нужно установить переменную DBUS_SESSION_BUS_ADDRESS. По умолчанию cron не имеет доступа к переменной. Чтобы исправить это, поместите куда-нибудь следующий скрипт и вызывайте его, когда пользователь входит в систему, например, используя awesome и функцию run_once, упомянутую в вики. Подойдет любой метод, так как не повредит, если функция будет вызываться чаще, чем требуется.

#!/bin/sh

touch $HOME/.dbus/Xdbus
chmod 600 $HOME/.dbus/Xdbus
env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus
echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus

exit 0

Это создает файл, содержащий необходимую переменную среды Dbus. Затем в скрипте, вызываемом cron, вы импортируете переменную, используя скрипт:

if [ -r "$HOME/.dbus/Xdbus" ]; then
  . "$HOME/.dbus/Xdbus"
fi
person thierrybo    schedule 30.10.2018

И, наконец, ужасное отсутствие cron (черт возьми)! Другими способами изменения вносятся в gconf, но изображение не меняется. Может быть, это потому, что я использую DDE Deepin (dde использует тот же путь, другой ключ). Гадкий на помощь: последняя попытка заставить эту сагу работать.

С помощью этого сценария обои меняются каждые 420 секунд (7 минут) в бесконечном цикле, выбирая случайные обои из одного из 4 наборов (или каталогов) в зависимости от времени дня или ночи.

Я создал файл .desktop и добавил этот файл .desktop в "~/.config/autostart". Я также создал еще одну пару скрипт/рабочий стол без цикла, чтобы он был на моей док-станции, поэтому я могу щелкнуть по нему и изменить его на лету.

Настройте уродство: сохраните скрипт как wallpaperd где-нибудь и сделайте его исполняемым:

chmod +x обои

Теперь создайте папку Wallpaper внутри каталога Pictures. Внутри этой папки с обоями создайте еще 4 папки с названиями день, закат, утро и ночь. Поместите нужные файлы изображений в эти 4 каталога.

mkdir -p ~/Изображения/Обои/утро
mkdir ~/Изображения/Обои/день
mkdir ~/Изображения/Обои/ночь
mkdir ~/Изображения/Обои/duskdawn

обои

#!/bin/bash

for (( ; ; ))
do

    me="MyUser" # Change me!
    morning="morning"
    afternoon="afternoon"
    dawn="duskdawn"
    night="night"
    dusk="duskdawn"
    now="morning"
    hour=$(date +%R | sed 's/\:.*//')

    if [ "$hour" -ge 7 ] && [ "$hour" -lt 12 ]
        then
        now="morning"
    elif [ "$hour" -ge 12 ] && [ "$hour" -lt 17 ]
        then
        now="afternoon"
    elif [ "$hour" -ge 17 ] && [ "$hour" -lt 18 ]
        then
        now="duskdawn"
    elif [ "$hour" -ge 18 ] && [ "$hour" -le 23 ]
        then
        now="night"
    elif [ "$hour" -ge 0 ] && [ "$hour" -lt 6 ]
        then
        now="night"
    elif [ "$hour" -ge 6 ] && [ "$hour" -lt 7 ]
        then
        now="duskdawn"
    fi

    imgPath="/home/$me/Pictures/Wallpaper/$now/"
    imgFile=$(ls -1 $imgPath | shuf -n 1 | awk '{print $NF}')

    export bgNow=""$imgPath$imgFile""

    # Deepin desktop
    /usr/bin/gsettings set com.deepin.wrap.gnome.desktop.background picture-uri "$bgNow"

    # Gnome desktop 
    #/usr/bin/gsettings set org.gnome.desktop.background picture-uri "$bgNow"  

  sleep 420

done
  • Установите правильную команду gsettings для вашего рабочего стола в сценарии!

Wallyd.desktop

** Путь автозапуска: /home/YOUR_USER/.config/autostart/wallyd.desktop**

[Desktop Entry]
Categories=System;
Comment=Change Wallpapers Agent
Exec=/home/$USER/Bin/wallpaperd
Icon=computer
Name=Wally Daemon
NoDisplay=false
Terminal=false
Type=Application
  • Измените путь к скрипту, чтобы он соответствовал пути, по которому вы сохранили скрипт.

Нет петли

Чтобы создать значок на рабочем столе без цикла, только чтобы изменить стену и выйти, сделайте следующее:

Сохраните скрипт как wallpaper (без буквы d в конце) и удалите следующие строки:

for (( ; ; ))
do

done

Используйте приведенный выше шаблон, чтобы создать еще один файл .desktop для этого незацикленного сценария обоев. Измените Имя и путь Exec для незацикленного скрипта.

Сохраните этот рабочий стол здесь:

/usr/доля/приложения/wally.desktop

Перетащите его на панель задач или в док-станцию. Нажмите на нее, и обои будут меняться на лету.

person Mach Seven    schedule 01.12.2019