Pisanie usystematyzowanej usługi do wykonania przy wznowieniu

15

mój laptop Dell jest objęty tym błędem w jądrze 3.14. Aby obejść ten problem, napisałem prosty skrypt

/ usr / bin /arity-fix:

#!/bin/bash

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

(i doprowadzany do stanu wykonalności: chmod +x /usr/bin/brightness-fix)

oraz usługę systemową wywołującą ją, która jest wykonywana podczas uruchamiania:

/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

i włączone: systemctl enable /etc/systemd/system/brightness-fix.service

Działa to jak urok i mogę kontrolować jasność wyświetlacza według potrzeb. Problem pojawia się, gdy laptop wznawia się po przejściu w tryb uśpienia (np. Po zamknięciu wargi laptopa): kontrola jasności nie działa, chyba że ręcznie wykonam powyższy skrypt fisrt:/usr/bin/brightness-fix

Jak mogę utworzyć inną usługę systemową, taką jak moja powyżej, która będzie wykonywana w czasie wznawiania?

EDYCJA: Zgodnie z poniższymi komentarzami zmodyfikowałem mój brightness-fix.servicetak:

[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

dodałem również echo "$1 $2" > /home/luca/br.logdo mojego skryptu, aby sprawdzić, czy jest on faktycznie wykonany. Skrypt jest faktycznie wykonywany również przy resume ( post suspend), ale nie ma żadnego efektu (podświetlany jest w 100% i nie można go zmienić). Próbowałem także rejestrować, $DISPLAYa $USERpo wznowieniu są one puste. Domyślam się, że skrypt jest uruchamiany zbyt wcześnie, gdy budzi się ze snu. Jakaś wskazówka?

lviggiani
źródło
2
WantedBy=sleep.target...
jasonwryan
Naprawdę?! Czy to takie proste ?! :) Czy mogę dodać „sleep.target” do mojego skryptu powyżej, czy mam utworzyć dla niego nowy dedykowany skrypt usługi systemowej?
lviggiani
... zgodnie z dokumentacją „Z tej opcji można skorzystać więcej niż jeden raz lub można podać listę nazw jednostek oddzieloną spacjami”. Spróbuję teraz.
lviggiani
Państwo musi go dodać do istniejącego pliku Systemd usług (które, nawiasem mówiąc, to nie skrypt, jest to statyczny plik konfiguracyjny). i na marginesie, Standard Hierarchii Systemów Plików stwierdza, że ​​właściwym miejscem do umieszczania skryptów, które sam napisałeś /usr/local/bin, nie jest /usr/bin. ten katalog jest zarezerwowany tylko dla menedżera pakietów.
strugee
2
Wierzę, że użycie sleep.targetspowoduje uruchomienie urządzenia, gdy komputer śpi, a nie po wznowieniu. Zobacz moją odpowiedź poniżej, aby znaleźć plik jednostki, który pracował dla mnie z podobnym problemem.
jat255

Odpowiedzi:

18

Wiem, że to stare pytanie, ale następujący plik jednostki działał dla mnie, aby uruchomić skrypt po wznowieniu ze stanu uśpienia:

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

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

[Install]
WantedBy=suspend.target

Wierzę, że to After=suspend.targetwłaśnie sprawia, że ​​działa on przy wznowieniu, a nie kiedy komputer idzie spać.

jat255
źródło
4
Współpracuje ze After=suspend.target w bloku i WantedBy=multi-user.target sleep.targetna Install .
Emmanuel,
Z powodzeniem używam następujących jednostek tutaj na Ubuntu 16.04 (elementarny Loki).
Naftuli Kay,
7

Alternatywnie do pisania i włączania pliku jednostkowego możesz również umieścić skrypt powłoki (lub dowiązanie symboliczne do skryptu) /lib/systemd/system-sleep/.

Zostanie wywołany przed snem / hibernacją oraz w czasie wznawiania.

Od man systemd-suspend.service:

Bezpośrednio przed wejściem w tryb zawieszenia systemu i / lub hibernacji systemd-suspend.service (i odpowiednio inne wymienione jednostki) uruchomi wszystkie pliki wykonywalne w / usr / lib / systemd / system-sleep / i przekaże im dwa argumenty. Pierwszym argumentem będzie „przed”, drugim „wstrzymanie”, „hibernacja” lub „hybrydowy sen” w zależności od wybranej akcji. Natychmiast po wyjściu z zawieszenia systemu i / lub hibernacji uruchamiane są te same pliki wykonywalne, ale pierwszym argumentem jest teraz „post”. Wszystkie pliki wykonywalne w tym katalogu są wykonywane równolegle, a wykonywanie akcji nie jest kontynuowane, dopóki wszystkie pliki wykonywalne nie zostaną zakończone.

Przetestuj to za pomocą:

#!/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
źródło
Strona /usr/lib/lib
podręcznika, do
@qdii: może to zależeć od dystrybucji i / lub wersji. W Debian 8 Jessie i Ubuntu 16.04 system-sleepkatalog wydaje się być w środku /lib/systemd/i /usr/lib/systemdzawiera inne rzeczy.
mivk
1

Kontynuacja odpowiedzi mivka, w której unikam muckingu z nowym plikiem jednostkowym (patrz moje pytanie tutaj Jak reagować na zdarzenia związane z pokrywą laptopa? ). Oto moje rozwiązanie; nie jest to w 100% proste ( westchnienie ), ponieważ system nie jest stabilny, gdy wychodzi ze snu:

Na moim pudełku Fedory 26 umieściłem tutaj link symboliczny: /usr/lib/systemd/system-sleep/sleepyheadktóry wskazuje tutaj: /root/bin/sleepyheadktóry zawiera:

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

Poniższy /root/bin/trackpointskrypt. Zauważ, że pierwszy sen jest krytyczny. Urządzenie jest konfigurowane przy każdym otwarciu pokrywy, więc na początku nie istnieje. Jeśli spróbuję zrobić coś innego niż sen, skrypt „sleepyhead” zajmie naprawdę dużo czasu, a mój wskaźnik zostanie zamrożony na co najmniej 60 sekund. Ponadto zauważ, że nie możesz umieścić /root/bin/trackpointskryptu w tle sleepyheadpowyżej. Jeśli to zrobisz, proces zostanie zabity po sleepyheadwyjściu.

#!/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.
źródło
Bardzo ładnie zorganizowane i udokumentowane. Dałbym ci wiele głosów, gdybym mógł!
MountainX