Systemd:如何使用电池启动/停止服务

Systemd:如何使用电池启动/停止服务

当笔记本电脑使用电池或登录时,有没有办法使用 systemd 来启动/停止服务?

作为开发人员,让 mongodb 和 redis 之类的程序自动启动很有帮助,但我想在使用电池时暂停它们,以尽可能节省。

答案1

我不是 systemd 专家,但我比一般人更擅长使用 Google。请参阅https://wiki.archlinux.org/index.php/Power_management

systemd 只做不到一件事(截至 systemd-204):根据系统是使用交流电还是电池供电来进行电源管理。为了填补这一空白,您可以创建一个 udev 规则,在交流适配器插入和拔出时运行脚本:

接下来是进一步的说明。

我猜你想做某事,比如创建一个名为 的虚假服务,acpluggedin.service该服务由 udev 规则启动和停止,然后让 mongo 和 redisRequires为其提供服务。或者其他什么。

答案2

这里有一篇关于此问题的很棒的文章:https://chrisdown.name/2017/10/29/adding-power-related-targets-to-systemd.html

选项1

基本上你必须做以下事情:

创建systemd启用交流电源的目标:

cat > /etc/systemd/system/ac.target << 'EOF'
[Unit]
Description=On AC power
DefaultDependencies=no
StopWhenUnneeded=yes
EOF

创建systemd使用电池供电的目标:

cat > /etc/systemd/system/battery.target << 'EOF'
[Unit]
Description=On battery power
DefaultDependencies=no
StopWhenUnneeded=yes
EOF

重新启动系统或者直接运行systemctl daemon-reload即可加载这些新的配置文件。

添加udev规则来触发状态改变:

cat > /etc/udev/rules.d/99-powertargets.rules << 'EOF'
SUBSYSTEM=="power_supply", KERNEL=="AC", ATTR{online}=="0", RUN+="/usr/sbin/systemctl start battery.target"
SUBSYSTEM=="power_supply", KERNEL=="AC", ATTR{online}=="1", RUN+="/usr/sbin/systemctl start ac.target"
EOF

现在重新启动系统或者直接运行udevadm control --reload-rules以激活新添加的udev配置文件。

此后,你可以使用以下命令查询当前系统状态

$ sudo systemctl status battery.target
● battery.target - On battery power
   Loaded: loaded (/etc/systemd/system/battery.target; static; vendor preset: disabled)
   Active: inactive (dead)

Oct 29 12:24:33 HOSTNAME systemd[1]: Reached target On battery power.
Oct 29 12:24:33 HOSTNAME systemd[1]: battery.target: Unit not needed anymore. Stopping.
Oct 29 12:24:33 HOSTNAME systemd[1]: Stopped target On battery power.

然后,您可以创建systemd使用这些新状态的新服务脚本。例如

$ systemctl cat powerdown.service
# /etc/systemd/system/powerdown.service
[Unit]
Description=Laptop battery savings

[Service]
Type=oneshot
ExecStart=/usr/local/bin/powerdown

[Install]
WantedBy=battery.target

选项 2

如果您真的不想处理所有systemd复杂性,您可以只使用udev部分并直接在其上运行脚本。

cat > /etc/udev/rules.d/99-my-battery-commands.rules << 'EOF'
SUBSYSTEM=="power_supply", KERNEL=="AC", ATTR{online}=="0", RUN+="/usr/local/bin/script-to-run-when-losing-ac-power"
SUBSYSTEM=="power_supply", KERNEL=="AC", ATTR{online}=="1", RUN+="/usr/local/bin/script-to-run-when-ac-power-restored"
EOF

并使用udevadm control --reload-rulesudevadm trigger似乎也能工作)来加载新配置。

如果您想要在某个 shell 脚本中知道当前是否有交流电,只需运行on_ac_power。如果已连接交流电,它会默默返回 true 退出代码,如果使用电池运行,则返回 false。但请注意,on_ac_power如果在没有电池的系统中运行(例如台式机系统),则返回 true 太愚蠢了。

相关内容