使用 cron 的 Gsettings
Posted
技术标签:
【中文标题】使用 cron 的 Gsettings【英文标题】:Gsettings with cron 【发布时间】:2012-05-09 14:41:00 【问题描述】:我编写了一个 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
【问题讨论】:
没有一个解决方案对我有用。 :( 我必须在 cron 表达式中的命令之前设置 DISPLAY=:0.0。(ubuntuforums.org/showthread.php?t=1023215)。P.s. 我正在尝试运行一个使用 pynotify 的 python 脚本。 @Hussain:我花了一些时间才开始提问。我敢打赌,我下面的答案应该会更好 - 只需阅读整个讨论即可。 【参考方案1】:最后是丑陋的,根本没有 cron(该死的)!使用其他方法可以在 gconf 中设置更改,但图像不会更改。也许是因为我在运行 Deepin 的 DDE(dde 使用相同的路径,不同的密钥)。丑陋的救援:让这个传奇成功的最后一次尝试。
使用此脚本,壁纸每 420 秒(7 分钟)更换一次,无限循环,根据白天或晚上的时间从 4 个集合(或目录)之一中选择随机壁纸。
我创建了一个 .desktop 文件并将这个 .desktop 文件添加到 “~/.config/autostart”。我还创建了另一对脚本/桌面,没有循环放在我的底座上,所以我也可以点击它并即时更改它。
设置丑陋:将脚本保存为 wallpaperd 某处并使其可执行:
chmod +x 壁纸
现在在 Pictures 目录中创建一个名为 Wallpaper 的文件夹。在此墙纸文件夹中再创建 4 个文件夹,名称分别为 afternoon、duskdawn、morning 和 night。将您想要的图像文件放在这 4 个目录中。
mkdir -p ~/Pictures/Wallpaper/morning 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
编辑脚本的路径以匹配您保存脚本的路径。
无循环
要创建一个不带循环的桌面图标,只需更改 Wally 并退出,请执行以下操作:
将脚本另存为 wallpaper(末尾不带 d)并删除以下行:
for (( ; ; ))
do
done
使用上面的模板为这个非循环 wallpaper 脚本创建另一个 .desktop 文件。更改非循环脚本的 Name 和 Exec 路径。
在此处保存此 .desktop:
/usr/share/applications/wally.desktop
将其拖到您的任务栏或停靠栏。单击它,它将动态更改壁纸。
【讨论】:
【参考方案2】:另请参阅对我有用的解决方案: https://unix.stackexchange.com/questions/111188/using-notify-send-with-cron#answer-111190 :
您需要设置 DBUS_SESSION_BUS_ADDRESS 变量。默认情况下,cron 无权访问该变量。为了解决这个问题,将以下脚本放在某个地方并在用户登录时调用它,例如使用 awesome 和 wiki 上提到的 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
【讨论】:
【参考方案3】:我找到了一些解决方案。当您导出文件 ~/.dbus/session-bus/* 中包含的变量 DBUS_SESSION_BUS_ADDRESS 时,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"
【讨论】:
【参考方案4】:经过多次尝试,我终于设法解决了这个问题。
确实,问题的出现是因为 cron 仅使用一组非常有限的环境变量。当设置为 cron 作业时,唯一一个负责以正确方式运行问题中的脚本的环境变量是 DBUS_SESSION_BUS_ADDRESS
,而不是 DISPLAY
或 XAUTHORITY
或 GSETTINGS_BACKEND
或其他东西。 this answer 也很好地指出了这一事实。
但this answer 中的问题是无法保证来自~/.dbus/session-bus/
目录的该文件中的DBUS_SESSION_BUS_ADDRESS
变量会更新为当前gnome 会话的当前值。要解决这个问题,一种方法是在当前 gnome 会话中查找进程的 PID,并从其环境中获取 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"
【讨论】:
非常感谢。我有一个脚本可以在午夜更新我的桌面壁纸。该脚本在几个月前停止正常工作。当我正常启动它时,它可以工作,但是从 crontab 中它没有完成这项工作。有了这个技巧,我可以解决问题。 对于双屏显示器,将选项spanned
更改为 zoom
感谢您的解决方案。我不得不稍微修改它以在 Debian 上使用 gnome-shell:PID=$(pgrep -o gnome-shell)
.
当 gnome-session 没有运行时会发生什么?
如果有多个用户登录怎么办?那么pgrep
会返回多个值【参考方案5】:
试过了,对我来说效果很好:
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
【讨论】:
如果您在交互式会话中使用它(例如ssh
)并且系统上正在运行一个单独的X11会话,则会出现问题;它似乎会导致某种减速或击键捕获,直到您的会话结束。 dbus
1.8.18 版的手册页指出:“要在 text\(hymode 会话中启动 D-Bus 会话,请不要使用 dbus-launch。相反,请参阅 **dbus-run-session**(1 )。”(我认为奇怪的\(
是格式错误。)不幸的是,dbus-run-session
似乎相当新,因为它在 Debian 8 中而不是 Debian 7 中。【参考方案6】:
添加 export DISPLAY=:0 && export XAUTHORITY=/home/username/.Xauthority ,其中 username 是您的 ubuntu 用户名。它应该修复 X11 授权错误。
【讨论】:
【参考方案7】:要通过 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
【讨论】:
以上是关于使用 cron 的 Gsettings的主要内容,如果未能解决你的问题,请参考以下文章