如何让XMonad环境中的电池检查脚本无条件运行?
解决XMonad中电池检查脚本无条件运行并正常触发通知的问题
一、先验证脚本是否在定时运行
首先确认后台线程是否真的在持续执行脚本:
- 在
~/.xmonad/check_battery.sh开头添加日志输出:
#!/bin/bash echo "$(date) : 执行电池检查" >> ~/.xmonad/battery_check_log.txt # 原脚本内容...
- 重启XMonad后,查看日志文件
~/.xmonad/battery_check_log.txt,如果每秒都有新的日志条目,说明脚本在正常定时运行,问题出在通知显示环节;如果日志没有更新,说明线程未正确启动。
二、如果脚本在运行但通知仅在输入后触发
1. 确保脚本获取正确的X环境变量
后台线程可能未继承DISPLAY变量,导致通知命令无法连接到X服务器。在脚本开头显式设置:
#!/bin/bash export DISPLAY=:0 # 本地X环境通常为:0,远程连接需调整 echo "$(date) : 执行电池检查" >> ~/.xmonad/battery_check_log.txt # 原脚本内容...
或者在Haskell代码中调用脚本时指定环境变量:
safeSpawn "bash" ["-c", "DISPLAY=:0 ~/.xmonad/check_battery.sh"]
2. 检查Dunst配置,禁用空闲隐藏通知
打开Dunst的配置文件(通常是~/.config/dunst/dunstrc或~/.config/dunst/dunst.conf),找到idle_hide选项并设置为no:
idle_hide = no
修改后重启Dunst:killall dunst && dunst &
三、如果脚本未定时运行
1. 选择正确的线程启动时机
优先在myStartupHook中启动后台线程,因为这个钩子是在XMonad完全初始化后执行的,环境变量更完整:
myStartupHook = do liftIO batteryCheck spawnOnce "dunst &" -- 其他启动项...
避免在main函数中过早启动(此时X环境可能未完全就绪)。
2. 确保脚本有执行权限
执行命令给脚本添加执行权限:
chmod +x ~/.xmonad/check_battery.sh
3. 检查Haskell代码中的线程逻辑
确认batteryCheck的线程创建逻辑正确,forkIO会创建独立后台线程,不会被XMonad的事件循环阻塞:
batteryCheck :: IO () batteryCheck = void $ forkIO $ forever $ do safeSpawn "bash" ["-c", "~/.xmonad/check_battery.sh"] threadDelay (1 * 1000000) -- 1秒间隔,可按需调整
内容的提问来源于stack exchange,提问作者Dzmitry
相关产品推荐
相关产品推荐

