udev 规则在交流电/电池插入/拔出事件上启动命令

udev 规则在交流电/电池插入/拔出事件上启动命令

为了节省电池,我想在笔记本电脑使用电池供电时关闭效果(合成器)。我想使用 udev 规则来实现这一点。

  • 创建了一个文件/etc/udev/rules.d/99-myrule.rules
ACTION=="change", SUBSYSTEM=="power_supply", RUN+="/usr/bin/startcompton.sh"

每次您连接/断开笔记本电脑上的 AC 时都会触发此规则。

然后我使用以下命令更新规则:sudo udevadm control -R

遗憾的是,连接/断开我的电源时这不会触发任何事情。

我的系统是 Arch linux。

答案1

总结:

  1. 让 udev 规则执行脚本以在 AC 断开连接时终止应用程序 (compton)。

  2. 重新启动它并不简单 - 创建一个 systemd 服务来启动您的应用程序,然后使用 udev 规则来启动该服务。

  3. 要测试你的 udev 规则,请使用udevadm control --reload-rules && udevadm trigger


回答:

所以我找到了一个可行的解决方案。这个问题由两个问题组成,让我们来分解一下:

  1. 编写 udev 规则以在 AC/电池插入/拔出时运行。
  2. 如何从 udev 规则启动像 compton 这样的 GUI 应用程序。

编写 udev 规则以在交流电/电池插入/拔出时运行:

创建文件/etc/udev/rules.d/60-onbattery.rules

# Rule for when switching to battery
SUBSYSTEM=="power_supply",ENV{POWER_SUPPLY_ONLINE}=="0",RUN+="/bin/killcompton.sh"

并创建文件/etc/udev/rules.d/61-onpower.rules

# Rule for when switching to powersupply
SUBSYSTEM=="power_supply",ENV{POWER_SUPPLY_ONLINE}=="1",RUN+="/bin/startcompton.sh"

注意POWER_SUPPLY_ONLINE周围环境ENV{...}

此外,如果你想了解你自己的规则的属性,可以使用以下命令监视 udev 看到的内容: udevadm monitor --environment

如果您的脚本只是一个后台任务,并且不调用任何与 GUI 相关的进程,那么您就大功告成了!否则,请继续阅读:

如何从 udev 规则启动像 compton 这样的 GUI 应用程序:

udev 人关于使用 RUN:

“这只能用于非常短暂的运行任务......”

这意味着我们应该使用一些持久的东西,比如systemd服务。创建服务文件/etc/systemd/system/compton.service::

[Unit]
Description=Start compton

[Service]
Type=simple
Environment="DISPLAY=:0"
Environment="XAUTHORITY=%h/.Xauthority"
User=USERNAME
ExecStart=/bin/compton --blur-method kawase --write-pid-path %t/compton.pid
PIDFile=%t/compton.pid

[Install]
WantedBy=default.target

替换USERNAME为您的用户名。

%h%t是被$HOME/run或替换的说明符$XDG_RUNTIME_DIRsystemd.unit(5)有关更多详细信息,请参阅。

Environment="XAUTHORITY=/home/USERNAME/.Xauthority"如果您想要一个 GUI 应用程序,则必须使用以下行。请参阅这个答案

最后,在您的 udev 规则中,不要启动您的 GUI 应用程序(在我们的例子中是 compton),而是启动服务:

SUBSYSTEM=="power_supply",ENV{POWER_SUPPLY_ONLINE}=="1",RUN+="/bin/systemctl start compton"

答案2

现有的答案让我开始了,但我想我会分享最终的结果 - 我的用例是在笔记本电脑失去交流电时做一些事情(实际上由于奇怪的 PSU 问题而对智能插头/继电器进行电源循环)。

我被绊倒了,因为 udev 规则不应该是多行的,如果是的话,它们应该被转义。

这就是我最终得到的结果:

# cat /etc/udev/rules.d/90-onbattery.rules                                                                                                                                                                                   
SUBSYSTEM=="power_supply",\
  ENV{POWER_SUPPLY_NAME}=="ADP1",\
  ENV{POWER_SUPPLY_ONLINE}=="0",\
  RUN+="/usr/bin/systemctl start power-cycle-outlet.service"
# cat /etc/systemd/system/power-cycle-outlet.service                                                                                                                                                                         
[Unit]
Description=Power Cycle Outlet via Home Assistant

[Service]
User=root
Type=simple
GuessMainPID=false
ExecStart=/usr/sbin/trigger-outlet-powercycle.sh

trigger-outlet-powercycle.sh进行网络调用,因此由于沙箱的原因,它不能直接从 udev 调用,我无法at工作,但 systemd 运行良好。

有趣的资源,可用于改进上述内容:

相关内容