acpid (简体中文)
acpid2是用于处理电源相关事件的守护进程,它非常灵活且易于扩展。当某个事件发生时,执行相关程序来处理该事件。这些事件是由某些动作触发的,比如:
- 按下电源按钮
- 按下睡眠/挂起按钮
- 合上笔记本盖子
- 拔下/插上笔记本外接电源
安装
使用Pacman 安装 acpid。 然后 start 并 enable acpid.service
.
配置
acpid预置了许多事件触发行为,比如它定义了当你按下电源按钮时应当发生什么。这些触发行为默认在/etc/acpi/handler.sh
中定义。在/etc/acpi/events/anything
)规定:任何侦测到的电源事件都会按照/etc/acpi/handler.sh
中定义的触发行为执行相关动作。
下面是一个定义触发行为的简单例子。在这个例子中,当按下睡眠按钮时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 ;;
不幸的是计算机上的这些电源事件标识并不统一,比如,在一些计算机上睡眠按钮可能被标识为SLPB,而在另一些计算机上为SBTN。
要想确定各种按钮或Fn
快捷键在你的计算机上是如何定义的:
# journalctl -f
现在在你计算机上按下电源按钮或睡眠按钮(比如Fn+Esc
),你会得到类似以下的结果:
logger: ACPI action undefined: PBTN logger: ACPI action undefined: SBTN
如果这不起作用的话,运行:
# acpi_listen
$ 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
像你看到的那样,在这个例子中睡眠按钮被识别为SBTN,而不是SLPB(这是/etc/acpi/handler.sh
中默认定义的标识符)。所以,要想让你的睡眠按钮正常工作的话,你需要编辑/etc/acpi/handler.sh
把SLPB)替换为SBTN)。
参照上面的例子,你应该可以很容易的通过定制/etc/acpi/handler.sh
来根据侦测到的电源时间来执行不同的命令。更多例子可参考下面的小技巧部分。
其它配置方案
默认所有的电源事件都是交由/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
最后,给脚本加上可执行权限:
# chmod +x /etc/acpi/actions/sleep-button.sh
用这种方法,你可以任意的独立的事件/行为脚本。
小技巧
脚本示例
下面给出的例子可以用在你的/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
音量调整
下面的一系列脚本是用来控制音量的。用上面讲到的方法找到音量键的标识符,然后替换掉下面文件中的事件标识就可以用在自己电脑上了:
/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
环境变量 environment variable,例如 sudo -u user XDG_RUNTIME_DIR=/run/user/1000 pactl
.参阅 [2].
获取当前登陆的用户名
你可以使用getuser
函数来获取当前登陆的用户名:
getuser () { export DISPLAY=`echo $DISPLAY | cut -c -2` user=`who | grep " $DISPLAY" | awk '{print $1}' | tail -n1` export XAUTHORITY=/home/$user/.Xauthority eval $1=$user }
然后这个函数就可以被用在下面的例子中,它可以在你按下电源按钮时正常的关闭KDE:
button/power) case "$2" in PBTN) getuser "$user" echo $user > /dev/tty5 su $user -c "dcop ksmserver ksmserver logout 0 2 0" ;; *) logger "ACPI action undefined $2" ;; esac ;;
连接到 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
.
参考
- http://acpid.sourceforge.net/ - acpid 主页
- Gentoo wiki