Ubuntu 20.04下自研程序如何检测电源按键以实现任务完成后关机
可行性说明
自研程序完全可以捕获到电源按键的按压事件。你之前接触的配置方案仅完成了“拦截系统默认电源键关机动作”的前置步骤,并未打通事件直接传递给自研程序的链路,因此才会出现禁用默认功能但无法对接自定义逻辑的问题。
实现步骤
第一步:彻底禁用系统层面对电源按键的默认响应
这一步的核心是把电源按键事件从系统默认的关机流程里剥离出来,避免事件被系统层面提前消费:
- 调整systemd-logind的电源键配置(Ubuntu 20.04默认由logind接管电源按键事件,无桌面环境时配置直接生效):编辑
/etc/systemd/logind.conf,找到HandlePowerKey配置项,将值修改为ignore,保存后执行sudo systemctl restart systemd-logind生效。 - 若系统中运行了acpid服务,需同步禁用acpid层面的电源键默认动作:注释或删除
/etc/acpi/events/路径下所有关联powerbtn的默认执行脚本配置,重启acpid服务sudo systemctl restart acpid。
完成上述配置后,短按电源按键不会触发任何系统默认的关机、休眠动作,事件会在输入子系统层面正常上报。
第二步:给自研程序对接事件捕获能力
适配纯TTY运行环境,有两种成熟的捕获方案可选:
方案1:自研程序直接读取evdev输入事件(无外部依赖,推荐)
Linux内核的evdev子系统会把所有物理按键的操作事件统一上报到/dev/input/路径下的事件节点中,电源按键属于标准输入设备,上报的事件码为KEY_POWER(数值为116)。
- 权限配置:将自研程序的运行账号加入
input用户组,否则无权限读取设备节点:sudo usermod -aG input 程序运行所属用户 - 程序逻辑实现:遍历系统下所有
/dev/input/event*设备节点,读取每个节点上报的input_event结构体,当匹配到「事件类型为EV_KEY、事件码为KEY_POWER、事件值为1(短按触发)」的条件时,就可以启动自定义流程:暂停新的测试任务下发,等待当前全量测试流程执行完成、拿到完整测试结果后,再调用systemctl poweroff执行最终关机操作。
方案2:通过acpid转发事件(减少自研程序底层开发量)
如果不想在自研程序中实现evdev读取逻辑,可以复用acpid的事件转发能力:
- 自定义acpi事件规则,新建配置文件
/etc/acpi/events/powerbtn_relay,写入如下规则:
event=button/power action=/opt/your_program/notify_power_pressed.sh
- 规则中指定的触发脚本只需要实现一个简单功能:给正在运行的自研程序发送自定义信号(如
SIGUSR1),自研程序收到对应信号后,即可启动等待任务完成再关机的逻辑。
关键注意事项
- 配置完成后先做验证:短按电源按键,确认系统无任何关机响应、无弹窗提示,即代表前置配置生效。
- 自研程序启动时可增加配置校验逻辑,检查logind的电源键配置是否为
ignore,避免后续系统更新导致配置被重置、事件被系统消费。 - 需将自研程序配置为multi-user.target下的开机自启服务,完全适配纯TTY的无图形运行环境。
- 4秒以上的长按触发的强制断电为主板/BIOS层面的硬件行为,软件层无法拦截,需在使用流程中提示操作人员短按电源键。
内容的提问来源于stack exchange,提问作者Elfreda
相关产品推荐
相关产品推荐

