Menulis layanan systemd untuk dieksekusi pada resume

15

laptop Dell saya mengalami bug ini dengan kernel 3.14. Sebagai solusinya saya menulis naskah sederhana

/ usr / bin / fix-fix:

#!/bin/bash

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

(dan membuat executable: chmod +x /usr/bin/brightness-fix)

dan layanan systemd memanggilnya yang dijalankan saat startup:

/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

dan diaktifkan: systemctl enable /etc/systemd/system/brightness-fix.service

Itu berfungsi seperti pesona dan saya dapat mengontrol kecerahan layar saya seperti yang diinginkan. Masalahnya muncul ketika laptop melanjutkan setelah masuk ke mode tidur (misalnya ketika menutup bibir laptop): kontrol kecerahan tidak berfungsi lagi kecuali saya secara manual menjalankan skrip fisrt saya di atas:/usr/bin/brightness-fix

Bagaimana saya bisa membuat layanan systemd lain seperti milik saya di atas yang akan dieksekusi pada waktu resume?

EDIT: Menurut komentar di bawah ini saya telah memodifikasi saya brightness-fix.serviceseperti ini:

[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

juga saya telah menambahkan echo "$1 $2" > /home/luca/br.logke skrip saya untuk memeriksa apakah itu benar-benar dieksekusi. Script itu sebenarnya dieksekusi juga di resume ( post suspend) tetapi tidak berpengaruh (backlit 100% dan tidak dapat diubah). Saya juga mencoba masuk $DISPLAYdan $USERdan, pada waktu resume, semuanya kosong. Jadi tebakan saya adalah bahwa skrip dieksekusi terlalu dini ketika bangun dari tidur. Ada petunjuk?

lviggiani
sumber
2
WantedBy=sleep.target...
jasonwryan
Betulkah?! Apakah itu sangat sederhana ?! :) Dapatkah saya menambahkan 'sleep.target' ke skrip saya di atas atau haruskah saya membuat skrip layanan systemd baru khusus untuk itu?
lviggiani
... menurut dokumentasi "Opsi ini dapat digunakan lebih dari sekali, atau daftar nama unit yang dipisahkan oleh ruang dapat diberikan". Saya akan coba sekarang.
lviggiani
Anda harus menambahkannya ke file layanan systemd yang ada (yang, omong-omong, bukan skrip; ini adalah file konfigurasi statis). dan sebagai catatan tambahan, Filesystem Hierarchy Standard menyatakan bahwa tempat yang tepat untuk menempatkan skrip yang Anda tulis sendiri adalah /usr/local/bintidak /usr/bin. direktori itu dicadangkan untuk manajer paket saja.
strugee
2
Saya percaya menggunakan sleep.targetakan menjalankan unit saat komputer tidur, bukan ketika itu dilanjutkan. Lihat jawaban saya di bawah untuk file unit yang bekerja untuk saya dengan masalah yang sama.
jat255

Jawaban:

18

Saya tahu ini adalah pertanyaan lama, tetapi file unit berikut ini berfungsi agar saya menjalankan skrip setelah melanjutkan dari tidur:

[Unit]
Description=<your description>
After=suspend.target

[Service]
User=root
Type=oneshot
ExecStart=<your script here>
TimeoutSec=0
StandardOutput=syslog

[Install]
WantedBy=suspend.target

Saya percaya itu After=suspend.targetyang membuatnya berjalan pada resume, bukan ketika komputer pergi tidur.

jat255
sumber
4
Bekerja dengan After=suspend.target di Unit dan WantedBy=multi-user.target sleep.targetdi Instal .
Emmanuel
Saya menggunakan unit-unit berikut dengan sukses di sini di Ubuntu 16.04 (SD Loki).
Naftuli Kay
7

Sebagai alternatif untuk menulis dan mengaktifkan file unit, Anda juga dapat memasukkan skrip shell (atau symlink ke skrip Anda) /lib/systemd/system-sleep/.

Ini akan dipanggil sebelum tidur / hibernasi, dan pada waktu melanjutkan.

Dari man systemd-suspend.service:

Segera sebelum memasuki sistem suspend dan / atau hibernasi systemd-suspend.service (dan unit-unit lain yang disebutkan, masing-masing) akan menjalankan semua executable di / usr / lib / systemd / system-sleep / dan menyampaikan dua argumen kepada mereka. Argumen pertama adalah "pre", yang kedua "suspend", "hibernate", atau "hybrid-sleep" tergantung pada tindakan yang dipilih. Segera setelah meninggalkan sistem menangguhkan dan / atau hibernasi executable yang sama dijalankan, tetapi argumen pertama sekarang "posting". Semua executable dalam direktori ini dieksekusi secara paralel, dan eksekusi action tidak dilanjutkan sampai semua executable selesai.

Uji dengan ini:

#!/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"
mivk
sumber
Halaman manual yang Anda tautkan menyebutkan file yang ditempatkan /usr/libtetapi semua contoh Anda merujuk ke file di bawah/lib
qdii
@qdii: mungkin tergantung pada distribusi dan / atau versi. Di Debian 8 Jessie dan Ubuntu 16.04, system-sleepdirektori tersebut tampaknya berada di /lib/systemd/, dan /usr/lib/systemdberisi hal-hal lain.
mivk
1

Tindak lanjuti jawaban mivk, di mana saya menghindari mucking dengan file unit baru (lihat pertanyaan saya di sini Bagaimana bereaksi terhadap peristiwa tutup laptop? ). Inilah solusi saya; itu tidak 100% langsung ( menghela nafas ) karena sistem tidak stabil ketika keluar dari tidur:

Pada kotak Fedora 26 saya menaruh symlink di sini: /usr/lib/systemd/system-sleep/sleepyheadyang menunjuk di sini /root/bin/sleepyhead:, yang berisi:

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

The /root/bin/trackpointScript berikut. Perhatikan bahwa tidur pertama sangat penting. Perangkat diatur setiap kali tutupnya dibuka, sehingga tidak ada pada awalnya. Jika saya mencoba melakukan sesuatu selain tidur, skrip "sleepyhead" membutuhkan waktu sangat lama untuk keluar dan pointer saya akan dibekukan selama setidaknya 60 detik. Selain itu, perhatikan bahwa Anda tidak dapat menempatkan /root/bin/trackpointskrip di latar belakang di sleepyheadatas. Jika Anda melakukannya, prosesnya akan mati ketika sleepyheadkeluar.

#!/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"
Mike S
sumber
Sangat terorganisir dan didokumentasikan dengan baik. Saya akan memberi Anda beberapa suara jika saya bisa!
MountainX-for-Monica