我的戴尔笔记本电脑受到这内核 3.14 的错误。作为解决方法,我编写了一个简单的脚本
/usr/bin/亮度修复:
#!/bin/bash
echo 0 > /sys/class/backlight/intel_backlight/brightnes
(并使其可执行chmod +x /usr/bin/brightness-fix
:)
以及一个在启动时调用它的 systemd 服务:
/etc/systemd/system/brightness-fix.service
[Unit]
Description=Fixes intel backlight control with Kernel 3.14
[Service]
Type=forking
ExecStart=/usr/bin/brightness-fix
TimeoutSec=0
StandardOutput=syslog
#RemainAfterExit=yes
#SysVStartPriority=99
[Install]
WantedBy=multi-user.target
并启用:systemctl enable /etc/systemd/system/brightness-fix.service
这就像一个魅力,我可以根据需要控制我的显示器亮度。当笔记本电脑进入睡眠模式后恢复时(例如,关闭笔记本电脑边缘时),问题就出现了:亮度控制不再起作用,除非我手动执行上面的第一个脚本:/usr/bin/brightness-fix
如何创建另一个像上面我的那样的 systemd 服务以在恢复时执行?
编辑:
根据下面的评论我已经修改了brightness-fix.service
这样的:
[Unit]
Description=Fixes intel backlight control with Kernel 3.14
[Service]
Type=oneshot
ExecStart=/usr/local/bin/brightness-fix
TimeoutSec=0
StandardOutput=syslog
[Install]
WantedBy=multi-user.target sleep.target
我还添加echo "$1 $2" > /home/luca/br.log
到我的脚本中以检查它是否实际执行。该脚本实际上也在resume( post suspend
)处执行,但没有任何效果(背光为100%且无法更改)。我也尝试过记录$DISPLAY
,$USER
并且在恢复时,它们是空的。所以我的猜测是从睡眠中醒来时脚本执行得太早了。有什么提示吗?
答案1
我知道这是一个老问题,但以下单元文件可以让我在从睡眠状态恢复时运行脚本:
[Unit]
Description=<your description>
After=suspend.target
[Service]
User=root
Type=oneshot
ExecStart=<your script here>
TimeoutSec=0
StandardOutput=syslog
[Install]
WantedBy=suspend.target
我相信正是它After=suspend.target
使其在恢复时运行,而不是在计算机进入睡眠状态时运行。
答案2
作为编写和启用单元文件的替代方法,您还可以将 shell 脚本(或脚本的符号链接)放入/lib/systemd/system-sleep/
.
它将在睡眠/休眠之前和恢复时调用。
在进入系统挂起和/或休眠之前,systemd-suspend.service(以及其他提到的单元)将运行 /usr/lib/systemd/system-sleep/ 中的所有可执行文件,并向它们传递两个参数。第一个参数为“pre”,第二个参数为“挂起”、“休眠”或“混合睡眠”,具体取决于所选操作。在离开系统挂起和/或休眠状态后,立即运行相同的可执行文件,但第一个参数现在是“post”。该目录中的所有可执行文件都是并行执行的,并且直到所有可执行文件都完成后才会继续执行该操作。
用这个测试一下:
#!/bin/sh
# This file (or a link to it) must be in /lib/systemd/system-sleep/
logger -t "test" "\$0=$0, \$1=$1, \$2=$2"
答案3
mivk 的答案的后续内容,其中我避免使用新的单元文件进行处理(请参阅我的问题如何对笔记本电脑盖子事件做出反应?)。这是我的解决方案;这不是 100% 简单(叹)因为系统从睡眠状态出来时不稳定:
在我的 Fedora 26 机器上,我在此处放置了一个符号链接:/usr/lib/systemd/system-sleep/sleepyhead
指向此处:/root/bin/sleepyhead
,其中包含:
#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/
# This is called when the lid is closed, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=pre, $2=suspend
# ...and when the lid is opened, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=post, $2=suspend
touch /tmp/sleepyrun
logger -t "sleepyhead" "Start: \$1=$1, \$2=$2"
if [ "$1" = "post" ] ; then
action="RUN trackpoint"
bash /root/bin/trackpoint >/tmp/trackpoint-run 2>&1
else
action="NO ACTION"
fi
logger -t "sleepyhead" "${action}: " "\$1=$1, \$2=$2"
脚本/root/bin/trackpoint
如下。请注意,第一次睡眠至关重要。每次打开盖子时都会设置该设备,因此一开始并不存在。如果我尝试做除睡眠之外的任何事情,“sleepyhead”脚本需要很长时间才能退出,并且我的指针将被冻结至少 60 秒。此外,请注意,您不能将上面的/root/bin/trackpoint
脚本置于后台sleepyhead
。如果这样做,进程将在sleepyhead
退出时被终止。
#!/bin/bash
# This is /root/bin/trackpoint
echo "Start $0"
date
found=false
dir=""
# dirlist can look like:
# /sys/devices/platform/i8042/serio1/serio25/speed
# /sys/devices/platform/i8042/serio1/serio24/speed
# ...the older one appears to get cleaned a little later.
sleep 1 # If I don't put this in here, my pointer locks up for a really long time...
for i in 1 2 3 4; do
speedfiles=$(find /sys/devices/platform/i8042 -name speed) # There may be multiple speed files at this point.
[ -z "$speedfiles" ] && { sleep 1; continue; }
dirlist=$(dirname $speedfiles)
printf "Speed file(s) at $(find /sys/devices/platform/i8042 -name speed | tail -1) \n"
# All this remaking of the path is here because the filenames change with
# every resume, and what's bigger: 9 or 10? ...Depends if you're
# lexicographical or numerical. We need to always be numerical.
largest_number="$(echo $dirlist | tr ' ' '\n' | sed -e 's/.*serio//' | sort -n | tail -1)"
dir="$(echo $dirlist | tr ' ' '\n' | egrep serio${largest_number}\$ )"
echo "Dir is $dir number is $largest_number"
[ -n "$dir" ] && found=true && break
done
$found || exit 1
date
echo -n 4 > $dir/inertia
echo -n 220 > $dir/sensitivity
echo -n 128 > $dir/speed
date
echo "Done $0"
答案4
仅供记录:
如果您需要以 root 身份执行某些操作,则还需要指定用户。
并且WantedBy=multi-user.target
让它在系统启动时自动运行。
StandardOutput=syslog
已弃用,可以安全地省略。
StandardOutput=journal
是新的默认值。
下面是在启动时和从待机状态返回时将音量静音的示例:
[Unit]
Description=Mute Audio on Startup and on resume from standby
After=sleep.target
[Service]
User=root
Type=oneshot
ExecStart=/usr/bin/amixer -D pulse sset Master mute
TimeoutSec=0
[Install]
WantedBy=multi-user.target sleep.target