Scrivere un servizio systemd da eseguire al curriculum


15

il mio laptop Dell è soggetto a questo bug con il kernel 3.14. Come soluzione alternativa ho scritto una sceneggiatura semplice

/ Usr / bin / luminosità-fix:

#!/bin/bash

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

(e reso eseguibile: chmod +x /usr/bin/brightness-fix)

e un servizio systemd che lo chiama che viene eseguito all'avvio:

/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

e abilitato: systemctl enable /etc/systemd/system/brightness-fix.service

Funziona come un incantesimo e posso controllare la luminosità del mio display come desiderato. Il problema si presenta quando il laptop riprende dopo essere passato in modalità di sospensione (ad es. Quando si chiude il labbro del laptop): il controllo della luminosità non funziona più se non eseguo manualmente il mio primo script sopra:/usr/bin/brightness-fix

Come posso creare un altro servizio di sistema come il mio sopra per essere eseguito al momento del ripristino?

EDIT: Secondo i commenti qui sotto ho modificato il mio in brightness-fix.servicequesto modo:

[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

inoltre ho aggiunto echo "$1 $2" > /home/luca/br.logal mio script per verificare se è effettivamente eseguito. Lo script viene effettivamente eseguito anche su resume ( post suspend) ma non ha alcun effetto (la retroilluminazione è al 100% e non può essere modificata). Ho anche provato la registrazione $DISPLAYe $USER, al momento del ripristino, sono vuoti. Quindi la mia ipotesi è che la sceneggiatura venga eseguita troppo presto al risveglio dal sonno. Qualche suggerimento?


2
WantedBy=sleep.target...
Jasonwryan,

Veramente?! È così semplice ?! :) Posso aggiungere 'sleep.target' al mio script sopra o devo creare un nuovo script di servizio systemd dedicato per esso?
lviggiani,

... secondo la documentazione "Questa opzione può essere utilizzata più di una volta oppure può essere fornito un elenco separato da spazi di nomi di unità". Ci proverò adesso.
lviggiani,

è necessario aggiungerlo al file di servizio systemd esistente (che, a proposito, non è uno script; è un file di configurazione statica). e come nota a margine, il Filesystem Hierarchy Standard afferma che il posto giusto per mettere gli script che avete scritto voi stessi è /usr/local/bin, non è /usr/bin. quella directory è riservata solo al gestore pacchetti.
strugee,

2
Credo che l'utilizzo di sleep.targetfarà funzionare l'unità quando il computer dorme, piuttosto che quando riprende. Vedi la mia risposta di seguito per un file di unità che ha funzionato per me con un problema simile.
jat255,

Risposte:


18

So che questa è una vecchia domanda, ma il seguente file di unità ha funzionato per me per eseguire uno script dopo aver ripreso dallo sleep:

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

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

[Install]
WantedBy=suspend.target

Credo che sia quello After=suspend.targetche lo fa funzionare al riavvio, piuttosto che quando il computer va in sospensione.


4
Funziona con After=suspend.target in Unit e WantedBy=multi-user.target sleep.targetin Install .
Emmanuel,

Sto usando le seguenti unità con successo qui su Ubuntu 16.04 (elementare Loki).
Naftuli Kay,

7

In alternativa alla scrittura e all'abilitazione di un file di unità, puoi anche inserire uno script di shell (o un link simbolico al tuo script) /lib/systemd/system-sleep/.

Verrà chiamato prima di dormire / ibernazione e al momento del ripristino.

Da man systemd-suspend.service:

Immediatamente prima di entrare nel sistema suspend e / o ibernazione systemd-suspend.service (e le altre unità menzionate, rispettivamente) eseguiranno tutti gli eseguibili in / usr / lib / systemd / system-sleep / e passeranno loro due argomenti. Il primo argomento sarà "pre", il secondo "sospensione", "ibernazione" o "sospensione ibrida" a seconda dell'azione scelta. Immediatamente dopo aver lasciato la sospensione del sistema e / o l'ibernazione vengono eseguiti gli stessi eseguibili, ma il primo argomento è ora "post". Tutti gli eseguibili in questa directory vengono eseguiti in parallelo e l'esecuzione dell'azione non viene continuata fino al termine di tutti gli eseguibili.

Provalo con questo:

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

La pagina man che colleghi menziona un file inserito /usr/libma tutti i tuoi esempi si riferiscono a file in/lib
qdii

@qdii: può dipendere dalla distribuzione e / o dalla versione. In Debian 8 Jessie e Ubuntu 16.04, la system-sleepdirectory sembra trovarsi /lib/systemd/e /usr/lib/systemdcontiene altre cose.
mivk

1

Seguito della risposta di Mivk, in cui evito di confondere con un nuovo file di unità (vedi la mia domanda qui Come reagire agli eventi del coperchio del laptop? ). Ecco la mia soluzione; non è semplice al 100% ( sospiro ) perché il sistema non è stabile quando esce dal sonno:

Sul mio box Fedora 26 ho messo un link simbolico qui: /usr/lib/systemd/system-sleep/sleepyheadche indica qui :, /root/bin/sleepyheadche contiene:

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

Lo /root/bin/trackpointscript segue. Si noti che il primo sonno è fondamentale. Il dispositivo viene installato ogni volta che si apre il coperchio, quindi all'inizio non esiste. Se provo a fare altro che dormire, lo script "dormiglione" impiega molto tempo per uscire e il mio puntatore rimarrà bloccato per almeno 60 secondi. Inoltre, tieni presente che non puoi inserire lo /root/bin/trackpointscript in background sleepyhead, sopra. Se lo fai, il processo verrà interrotto quando si sleepyheadesce.

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

Molto ben organizzato e documentato. Ti darei più voti se potessi!
MountainX-for-Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.