当笔记本电脑使用电池或登录时,有没有办法使用 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-rules
(udevadm trigger
似乎也能工作)来加载新配置。
如果您想要在某个 shell 脚本中知道当前是否有交流电,只需运行on_ac_power
。如果已连接交流电,它会默默返回 true 退出代码,如果使用电池运行,则返回 false。但请注意,on_ac_power
如果在没有电池的系统中运行(例如台式机系统),则返回 true 太愚蠢了。