0

我编写了一个 POSIX shell 脚本来提醒我使用 notify-send 和 cronjob 的电池寿命,但是我遇到了 DBUS 问题


这是脚本的样子

#!/bin/sh

percent=`upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep percentage:

notify-send "battery life" "$percent"

它按预期工作,并在调用时弹出此通知。

我写了这个脚本是因为我的窗口管理器 i3 缺少电池状态通知系统,所以我发现自己的笔记本电脑电池没电了,即使我就在家里的插座旁边。

当然; 拥有这样的脚本是没有意义的,除非它会自动弹出,所以经过一番摆弄之后,我设置了一个每 10 分钟运行一次脚本的 Cron 作业。

这是 cron-tab 的样子:
*/10 * * * * export DISPLAY=:0 ; export DBUS_SESSION_BUS_ADDRESS=a; batterystatus.sh

它可以工作,除了没有关于 DBUS_SESSION_BUS_ADDRESS 东西的小片段,由于某种原因notify-status不起作用。

所以,一切都很酷,直到我重新启动并发现 cron-tab: 中使用的这个值unix:abstract=/tmp/dbus-FOSTebXqX5,guid=a7ad198d91d224b8c056efc6615a3610在启动时发生了变化。
这意味着我每次启动计算机时都必须更改 cron-job,以便脚本能够正常工作。

有没有办法解决?

4

1 回答 1

0

与其使用crontab,不如使用systemd。您可以拥有 systemd 用户服务和计时器,以便 D-Bus 可以访问会话 D-Bus 信息以获取会话通知。

我已经使用 Python dbus 库pydbus作为示例总线对此进行了测试,我相信您也可以使用您的 shell 脚本。

用于获取电池电量和发布通知的 Python 脚本:

#!/usr/bin/python3
import pydbus

sys_bus = pydbus.SystemBus()
ses_bus = pydbus.SessionBus()

power = sys_bus.get('.UPower', '/org/freedesktop/UPower/devices/battery_BAT0')
notifications = ses_bus.get('.Notifications')

print(power.Percentage)

notifications.Notify('test', 0, 'dialog-information', "Battery Notification!",
                     f"Percentage: {power.Percentage}%", [], {}, 5000)

在以下位置创建了用户服务/etc/systemd/user/battery.service

[Unit]
Description=Check for battery percentage

[Service]
Type=dbus
BusName=org.freedesktop.Notifications
ExecStart=/home/thinkabit1/stack_overflow/battery_monitor.py

您可以使用以下方法测试此功能:

$ systemctl --user start battery.service

要查看服务的状态,请执行以下操作:

$ systemctl --user status battery.service

要让计时器每 10 分钟运行一次,请创建/etc/systemd/user/battery.timer

[Unit]
Description=Run battery monitor every 10 minutes

[Timer]
OnBootSec=10min
OnUnitActiveSec=10min

[Install]
WantedBy=timers.target

这可以从以下开始:

$ systemctl --user start battery.timer

要查看状态:

$ systemctl --user list-timers

要让它在重新启动后自动启动,请使用:

systemctl --user enable battery.timer
于 2021-10-04T08:00:35.520 回答