web-dev-qa-db-ja.com

再開時に実行されるsystemdサービスの作成

私のDellラップトップは、カーネル3.14の this バグの影響を受けます。回避策として、簡単なスクリプトを書きました

/ usr/bin/brightness-fix:

#!/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

これは魅力のように機能し、必要に応じてディスプレイの明るさを制御できます。問題は、ラップトップがスリープモードになった後(ラップトップのリップを閉じたときなど)再開したときに発生します。上記のfisrtスクリプトを手動で実行しない限り、明るさ制御は機能しなくなります。/usr/bin/brightness-fix

上記の私のような別のsystemdサービスを作成して再開時に実行するにはどうすればよいですか?

EDIT:以下のコメントによると、私は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を追加して、実際に実行されるかどうかを確認しています。再開時に実際に実行されるスクリプト(post suspend)ですが、効果はありません(バックライトは100%で変更できません)。また、$DISPLAY$USERをログに記録してみましたが、再開時には空です。つまり、スクリプトは、スリープから復帰したときに実行が早すぎると思います。ヒントはありますか?

16
lviggiani

これは古い質問であることはわかっていますが、次のユニットファイルは、スリープから再開したときにスクリプトを実行するのに役立ちました。

[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これにより、コンピュータがスリープ状態になったときではなく、再開時に実行されます。

20
jat255

ユニットファイルを作成して有効にする代わりに、シェルスクリプト(またはスクリプトへのシンボリックリンク)を/lib/systemd/system-sleep/

スリープ/休止状態の前、および再開時に呼び出されます。

から man systemd-suspend.service

システムサスペンドまたはハイバネーション(またはその両方)に入る直前に、systemd-suspend.service(およびその他の言及されたユニット)はすべて、/ usr/lib/systemd/system-sleep /内のすべての実行可能ファイルを実行し、2つの引数を渡します。選択したアクションに応じて、最初の引数は「pre」、2番目の引数は「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"
7
mivk

Mivkの回答のフォローアップ。ここでは、新しいユニットファイルをいじるのを避けています(私の質問はこちら ラップトップのふたのイベントにどのように反応するのですか? )。これが私の解決策です。 100%単純明快ではありません(sigh)システムはスリープ状態から脱出すると安定しないためです。

私の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秒間フリーズします。さらに、上記のsleepyheadでは、/root/bin/trackpointスクリプトをバックグラウンドで配置できないことに注意してください。実行すると、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"
1
Mike S