编写要在履历表上执行的系统服务


15

我的戴尔笔记本电脑的内核3.14 受此错误影响。作为解决方法,我编写了一个简单的脚本

/ usr / bin /亮度修复:

#!/bin/bash

echo 0 > /sys/class/backlight/intel_backlight/brightnes

(和由可执行:chmod +x /usr/bin/brightness-fix

以及在启动时执行的调用它的系统服务:

/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

这就像一种魅力,我可以根据需要控制显示屏的亮度。问题出在笔记本电脑进入睡眠模式后恢复正常运行时(例如,当合上笔记本电脑的嘴唇时):亮度控制不再起作用,除非我手动执行上面的fisrt脚本:/usr/bin/brightness-fix

如何创建另一个像我上面的系统服务,以便在恢复时执行?

编辑: 根据下面的评论,我已经修改了我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并且在恢复时它们为空。因此,我的猜测是该脚本从睡眠中唤醒时执行得太早了。有什么提示吗?


2
WantedBy=sleep.target...
jasonwryan 2014年

真?!这么简单吗?:)我可以在上面的脚本中添加'sleep.target'还是为它创建一个新的专用systemd服务脚本?
lviggiani 2014年

...根据文档,“此选项可以多次使用,或者可以用空格分隔的单位名称列表”。我现在尝试。
lviggiani 2014年

必须将其添加到现有的systemd服务文件(顺便说一句,它不是脚本;它是静态配置文件)。另外,文件系统层次结构标准指出,放置您自己编写的脚本的正确位置/usr/local/bin不是/usr/bin。该目录仅保留给程序包管理器。
2014年

2
我相信使用sleep.target会在计算机休眠时(而不是在恢复时)运行该单元。请参阅以下我的答案,以获取适用于我的类似问题的单位文件。
jat255 2015年

Answers:


18

我知道这是一个老问题,但是以下单位文件对我起作用,以便在从睡眠状态恢复时运行脚本:

[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因为它使它可以在简历上运行,而不是在计算机进入睡眠状态时运行。


4
与工作 After=suspend.target单位,并 WantedBy=multi-user.target sleep.target安装
伊曼纽尔

我在Ubuntu 16.04(基本Loki)上成功使用了以下单元
Naftuli Kay

7

作为编写和启用单位文件的替代方法,您还可以将Shell脚本(或指向脚本的符号链接)放入/lib/systemd/system-sleep/

它将在睡眠/休眠之前以及恢复时间被调用。

来自man systemd-suspend.service

在进入系统挂起和/或休眠状态之前,systemd-suspend.service(以及分别提到的其他单元)将在/ usr / lib / systemd / system-sleep /中运行所有可执行文件,并将两个参数传递给它们。第一个参数为“ pre”,第二个参数为“ suspend”,“ hibernate”或“ hybrid-sleep”,具体取决于所选的操作。在使系统挂起和/或休眠后,立即运行相同的可执行文件,但第一个参数现在为“ 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"

您链接的手册页中提到了放置的文件,/usr/lib但所有示例均参考/lib
qdii

@qdii:它可能取决于发行版和/或版本。在Debian 8 Jessie和Ubuntu 16.04中,该system-sleep目录似乎位于中/lib/systemd/,并且/usr/lib/systemd包含其他内容。
mivk

1

对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 in background"
    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"

非常好的组织和记录。如果可以的话,我会给你多票!
MountainX-for-Monica,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.