acpid
acpid2是用於處理電源相關事件的守護進程,它非常靈活且易於擴展。當某個事件發生時,執行相關程序來處理該事件。這些事件是由某些動作觸發的,比如:
- 按下電源按鈕
- 按下睡眠/掛起按鈕
- 合上筆記本蓋子
- 拔下/插上筆記本外接電源
安裝[編輯 | 編輯原始碼]
使用Pacman 安裝 acpid包。 然後 start/enable acpid.service
.
配置[編輯 | 編輯原始碼]
確定事件名稱[編輯 | 編輯原始碼]
不幸的是計算機上的這些電源事件標識並不統一,比如,在一些計算機上睡眠按鈕可能被標識為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包預置了許多事件觸發行為,比如它定義了當你按下電源按鈕時應當發生什麼。這些觸發行為默認在/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 ;;
如果睡眠按鈕被識別為SBTN,而不是 /etc/acpi/handler.sh
中默認定義的 SLPB(這是標識符)。需要編輯/etc/acpi/handler.sh
把SLPB)替換為SBTN)。
參照上面的例子,你應該可以很容易的通過定製/etc/acpi/handler.sh
來根據偵測到的電源時間來執行不同的命令。更多例子可參考下面的小技巧部分。
button/power
, button/lid
, button/suspend
and button/hibernate
are handled by systemd-logind.service(8) by default, see Power management#Power management with systemd. If handling these events with acpid, the handling of these events by logind should either be disabled first, or inhibited.其它配置方案[編輯 | 編輯原始碼]
默認所有的電源事件都是交由/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
最後,給腳本加上 executable 可執行權限: 並 reload acpid.service
。
這種方法可以簡化的獨立事件和行為腳本的處理。
小技巧[編輯 | 編輯原始碼]
腳本示例[編輯 | 編輯原始碼]
下面給出的例子可以用在你的/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
Enabling backlight control[編輯 | 編輯原始碼]
Similar to volume control, acpid also enables you to control screen backlight. To achieve this you write some handler, like this:
/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
and again, connect keys to ACPI events:
/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 +
音量調整[編輯 | 編輯原始碼]
下面的一系列腳本是用來控制音量的。用上面講到的方法找到音量鍵的標識符,然後替換掉下面文件中的事件標識就可以用在自己電腦上了:
/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].
Disabling ordinary key events[編輯 | 編輯原始碼]
Since b336c96 acpid generates events for some ordinary key presses, such as arrow keys. This results in event/handler spam, visible in system logs or top. Events for these buttons can be dropped in the configuration file:
/etc/acpi/events/buttons
event=button/(up|down|left|right|kpenter) action=<drop>
獲取當前登錄的用户名[編輯 | 編輯原始碼]
你可以使用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
.
Disable keyboard and touchpad while laptop lid is closed under Wayland[編輯 | 編輯原始碼]
This example uses inhibited property of input device drivers as a replacement for xinput which does not work under 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 ;;