acpid
acpid2 是一个灵活且可扩展的守护进程,用于传递 ACPI 事件。 当事件发生时,它会执行程序来处理该事件。 这些事件由某些操作触发,例如
- 按下特殊按键,包括电源/睡眠/挂起按钮
- 合上笔记本电脑盖子
- (拔下)笔记本电脑的交流电源适配器
- (拔下)电话插孔等。
安装
安装 acpid 软件包。 然后 启动/启用 acpid.service
。
配置
acpid 附带了许多针对触发事件的预定义操作,例如当您按下机器上的电源按钮时应该发生什么。 默认情况下,这些操作在 /etc/acpi/handler.sh
中定义,该脚本在检测到任何 ACPI 事件后执行(由 /etc/acpi/events/anything
确定)。
确定事件
不幸的是,并非每台计算机都以相同的方式标记 ACPI 事件。 例如,在一台机器上,睡眠按钮可能被识别为 SLPB,而在另一台机器上则被识别为 SBTN。
要确定您的按钮或 Fn
快捷键如何被识别,请运行以下命令
# journalctl -f
现在按下您机器上的电源按钮和/或睡眠按钮(例如 Fn+Esc
)。 结果应该看起来像这样
logger: ACPI action undefined: PBTN logger: ACPI action undefined: SBTN
如果这不起作用,请运行
# acpi_listen
或者使用 openbsd-netcat
$ netcat -U /var/run/acpid.socket
然后按下电源按钮,您将看到类似这样的内容
button/power PBTN 00000000 00000b31
acpi_listen
的输出作为 $1、$2、$3 和 $4 参数发送到 /etc/acpi/handler.sh
。 例子
$1 button/power $2 PBTN $3 00000000 $4 00000b31
定义事件动作
以下是其中一个动作的简短示例。 在这种情况下,当按下睡眠按钮时,acpid 运行命令 echo -n mem >/sys/power/state
,这应该使计算机进入睡眠(挂起)状态
button/sleep) case "$2" in SLPB) echo -n mem >/sys/power/state ;; *) logger "ACPI action undefined: $2" ;; esac ;;
在不同的机器上,事件可能有所不同。 例如,如果睡眠按钮实际上被识别为 SBTN,而不是默认 /etc/acpi/handler.sh
中指定的 SLPB 标签。 为了使睡眠功能在这台机器上正常工作,我们需要将 SLPB) 替换为 SBTN)。
使用此信息作为基础,您可以轻松自定义 /etc/acpi/handler.sh
文件,以根据触发的事件执行各种命令。 有关其他常用命令,请参见下面的 #技巧与诀窍 部分。
button/power
、button/lid
、button/suspend
和 button/hibernate
之类的事件默认由 systemd-logind.service(8) 处理,请参阅 电源管理#ACPI 事件。 如果使用 acpid 处理这些事件,则应首先禁用或抑制 logind 对这些事件的处理。其他配置
默认情况下,所有 ACPI 事件都通过 /etc/acpi/handler.sh
脚本传递。 这是由于 /etc/acpi/events/anything
中概述的规则集
# Pass all events to our one handler script event=.* action=/etc/acpi/handler.sh %e
虽然这可以正常工作,但有些用户可能更喜欢在他们自己的自包含脚本中定义事件规则和操作。 以下是如何使用单个事件文件和相应操作脚本的示例
以 root 身份,创建以下文件
/etc/acpi/events/sleep-button
event=button/sleep.* action=/etc/acpi/actions/sleep-button.sh %e
/etc/acpi/actions/sleep-button.sh
#!/bin/sh case "$3" in SLPB) echo -n mem >/sys/power/state ;; *) logger "ACPI action undefined: $3" ;; esac
使脚本 可执行,并 重新加载 acpid.service
以使 acpid 识别对这些文件的更改。
使用此方法,可以轻松创建任意数量的单独事件/操作脚本。
技巧与诀窍
示例事件
以下是可以在 /etc/acpi/handler.sh
脚本中使用的事件示例。 应该修改这些示例,使其适用于您的特定环境,例如更改 acpi_listen
解释的事件变量名称。
设置笔记本电脑屏幕亮度,无论是否插入电源(数字可能需要调整,请参阅 /sys/class/backlight/acpi_video0/max_brightness
)
ac_adapter) case "$2" in AC*|AD*) case "$4" in 00000000) echo -n 50 > /sys/class/backlight/acpi_video0/brightness ;; 00000001) echo -n 100 > /sys/class/backlight/acpi_video0/brightness ;; esac
启用音量控制
找出音量按钮的 acpi 标识(见上文),并将其替换为下面文件中的 acpi 事件。
/etc/acpi/events/vol-d
event=button/volumedown action=amixer set Master 5-
/etc/acpi/events/vol-m
event=button/mute action=amixer set Master toggle
/etc/acpi/events/vol-u
event=button/volumeup action=amixer set Master 5+
XDG_RUNTIME_DIR
环境变量 时,以当前用户身份运行命令,例如使用# sudo -u user XDG_RUNTIME_DIR=/run/user/user_id pactl
另请参阅 [2]。
启用背光控制
与音量控制类似,acpid 也使您能够控制屏幕背光。 为了实现这一点,您需要编写一些处理程序,例如这样
/etc/acpi/handlers/bl
#!/bin/sh bl_dev=/sys/class/backlight/acpi_video0 step=1 case $1 in -) echo $(($(< $bl_dev/brightness) - $step)) >$bl_dev/brightness;; +) echo $(($(< $bl_dev/brightness) + $step)) >$bl_dev/brightness;; esac
acpi_listen 中的事件应该类似于
video/brightnessdown BRTDN 00000087 00000000 video/brightnessup BRTUP 00000086 00000000
将它们连接到 ACPI 事件
/etc/acpi/events/bl_d
event=video/brightnessdown.* action=/etc/acpi/handlers/bl -
/etc/acpi/events/bl_u
event=video/brightnessup.* action=/etc/acpi/handlers/bl +
启用 Wi-Fi 开关
您还可以通过按下 WLAN 按钮来创建一个简单的无线电源开关。 事件示例
/etc/acpi/events/wlan
event=button/wlan action=/etc/acpi/handlers/wlan
及其处理程序
/etc/acpi/handlers/wlan
#!/bin/sh rf=/sys/class/rfkill/rfkill0 case $(< $rf/state) in 0) echo 1 >$rf/state;; 1) echo 0 >$rf/state;; esac
禁用普通按键事件
由于 b336c96 acpid 为某些普通按键按下(例如箭头键)生成事件。 这会导致事件/处理程序垃圾邮件,在系统日志或 top 中可见。 这些按钮的事件可以在配置文件中删除
/etc/acpi/events/buttons
event=button/(up|down|left|right|kpenter) action=<drop>
获取当前显示的用户名称
要根据 Xorg 运行命令,需要定义 X 显示以及 MIT 魔法 cookie 文件(通过 XAUTHORITY)。 后者是安全凭据,提供对 X 服务器、显示和任何输入设备的读写访问权限(请参阅 xauth(1))。
- 如果在盖子关闭时 LCD 背光灯未关闭,您可以手动执行此操作,方法是在盖子关闭和盖子打开事件时分别运行
getXuser xset dpms force off
和getXuser xset dpms force on
。 如果显示器已变黑,但背光灯仍然亮着,请改用 vbetool 以及vbetool dpms off
和vbetool dpms on
。 另请参阅 XScreenSaver#配置。 - 当使用 who 或 w 时,请确保在启动时创建
/run/utmp
。 有关详细信息,请参阅 utmp(5)。
连接到 acpid 套接字
除了规则文件外,acpid 还接受 UNIX 域套接字上的连接,默认情况下为 /var/run/acpid.socket
。 用户应用程序可以连接到此套接字。
#!/bin/bash coproc acpi_listen trap 'kill $COPROC_PID' EXIT while read -u "${COPROC[0]}" -a event; do handler.sh "${event[@]}" done
其中 handler.sh
可以是类似于 /etc/acpi/handler.sh
的脚本。
在 Wayland 下笔记本电脑盖子关闭时禁用键盘和触摸板
此示例使用输入设备驱动程序的 inhibited 属性来代替 xinput,后者在 Wayland 下不起作用。
button/lid) if echo "$3" | grep -iq "open"; then echo 'LID opened' disabled=0 fi if echo "$3" | grep -iq "close"; then echo 'LID closed' disabled=1 fi find /sys/devices/platform/i8042/serio* -prune -type d | while IFS= read -r serionumber; do find $serionumber/input/* -prune -type d | while IFS= read -r inputdevicepath; do if grep -q -i -e "keyboard" -e "touchpad" $inputdevicepath/name; then logger "found $(cat $inputdevicepath/name) and set to $disabled" echo $disabled > $inputdevicepath/inhibited fi done done ;;