在我的树莓派(正在运行树莓派)上,我想在闲置系统5分钟(无鼠标或键盘操作)之后通过wmctrl -s 0和xprintidle将当前桌面切换到桌面n#0,以检查空闲时间。
请记住,我不是专家...
我尝试了两种不同的方法,但没有一种有效,我想知道哪种方法是完成工作的最佳方法:
bash脚本和crontab
我编写了一个简单的脚本,该脚本检查xprintidle是否大于先前设置的$IDLE_TIME,是否大于切换桌面(保存在/usr/local/bin/switchDesktop0OnIdle中):
#!/bin/bash
# 5 minutes in ms
IDLE_TIME=$((5*60*1000))
# Sequence to execute when timeout triggers.
trigger_cmd() {
wmctrl -s 0
}
sleep_time=$IDLE_TIME
triggered=false
while sleep $(((sleep_time+999)/1000)); do
idle=$(xprintidle)
if [ $idle -ge $IDLE_TIME ]; then
if ! $triggered; then
trigger_cmd
triggered=true
sleep_time=$IDLE_TIME
fi
else
triggered=false
# Give 100 ms buffer to avoid frantic loops shortly before triggers.
sleep_time=$((IDLE_TIME-idle+100))
fi
done
脚本本身有效。
然后我将其添加到crontab(crontab -e)中,以使其每6分钟运行一次
*/6 * * * * * sudo /usr/local/bin/switchDesktop0OnIdle
不确定是否需要sudo。
无论如何,它是行不通的:谷歌搜索我了解crontab在具有自己变量的环境中运行。即使我不记得如何访问该环境(糟糕),我也确实记得在运行脚本的过程中遇到了这两个错误(在"正常" shell中正确运行)
could not open display(重要吗?)
bla bla -ge error, unary operator expected或类似的东西:xprintidle基本上在这种环境下不起作用a会返回一个空值
我想念什么?
无限时bash脚本作为守护程序运行
第二种方法是,我尝试使用内部无限设置脚本,同时检查xprintidle是否大于5分钟。在这种情况下,桌面已切换(不太优雅吗?)。也保存在/usr/local/bin/switchDesktop0OnIdle中
#!/bin/bash
triggered=false
while :
do
if [ `xprintidle` -ge 300000 ]; then
if [ triggered == false ]
wmctrl -s 0
triggered = true
fi
else
triggered = false
fi
fi
done
脚本本身再次起作用。
我试图在/etc/init.d/switchDesktop0OnIdle中创建一个守护程序(在这里真的不是专家,修改了一个现有的守护程序)
#! /bin/sh
# /etc/init.d/switchDesktop0OnIdle
### BEGIN INIT INFO
# Provides: switchDesktop0OnIdle
# Required-Start: $all
# Required-Stop: $all
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description:
# Description:
### END INIT INFO
DAEMON=/usr/local/bin/switchDesktop0OnIdle
NAME=switchDesktop0OnIdle
test -x $DAEMON || exit 0
case"$1" in
start)
echo -n"Starting daemon:"
start-stop-daemon --start --exec $DAEMON
echo"switchDesktop0OnIdle."
;;
stop)
echo -n"Shutting down daemon:"
start-stop-daemon --stop --oknodo --retry 30 --exec $DAEMON
echo"switchDesktop0OnIdle."
;;
restart)
echo -n"Restarting daemon:"
start-stop-daemon --stop --oknodo --retry 30 --exec $DAEMON
start-stop-daemon --start --exec $DAEMON
echo"switchDesktop0OnIdle."
;;
*)
echo"Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
我设置好了
sudo update-rc.d switchDesktop0OnIdle defaults
和
sudo service switchDesktop0OnIdle start
(必要?)
...什么也没有发生...
我也没有找到ps -ef | grep switchDesktop0OnIdle的进程,但是似乎在sudo service switchDesktop0OnIdle status上运行
谁能帮忙吗?
谢谢
朱塞佩
正如您所怀疑的那样,问题是当您从init或cron运行脚本时,它们不在您希望它们控制的GUI环境中运行。原则上,Linux系统可以运行多个X环境。当您使用一个可执行文件时,会有一些环境变量将使用的可执行文件定向到您所在的环境。
解决方案有两个部分:脚本必须知道它们在哪个环境上运行,并且它们必须具有与该环境交互的权限。
几乎可以肯定,您使用的DISPLAY值为":0",因此脚本开始处的export DISPLAY=:0将处理问题的第一部分。 (它可能是":0.0",实际上是等效的)。
授权要复杂一些。可以将X设置为以不同的方式进行授权,但是最常见的是在主目录中具有一个文件.Xauthority,该文件包含X服务器检查的令牌。如果您在自己的crontab中安装脚本,它将在您自己的用户ID下运行(您不应该使用sudo),因此它将读取正确的.Xauthority文件。如果从root crontab或init脚本运行,它将以root用户身份运行,因此它可以访问所有内容,但仍然需要知道从何处获取令牌。我认为将export XAUTHORITY=/home/joe/.Xauthority添加到脚本中将起作用。 (假设您的用户名是joe。)
非常感谢你,它奏效了