Escrevendo um serviço systemd para ser executado no currículo

14

meu laptop Dell está sujeito a este bug com o kernel 3.14. Como solução, escrevi um script simples

/ usr / bin / brilho-fix:

#!/bin/bash

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

(e feito executável: chmod +x /usr/bin/brightness-fix )

e um serviço systemd chamando-o que é executado na inicialização:

/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 ativado: systemctl enable /etc/systemd/system/brightness-fix.service

Isso funciona como um encanto e posso controlar o brilho da minha tela como desejado. O problema surge quando o laptop é reiniciado após o modo sleep (por exemplo, ao fechar o lábio do laptop): o controle de brilho não funciona mais, a menos que eu execute manualmente o meu primeiro script acima: /usr/bin/brightness-fix

Como posso criar outro serviço systemd como o meu acima para ser executado no tempo de reinicialização?

EDITAR: De acordo com os comentários abaixo, modifiquei meu brightness-fix.service da seguinte forma:

[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

também adicionei echo "$1 $2" > /home/luca/br.log ao meu script para verificar se ele é realmente executado. O script é realmente executado também no resumo ( post suspend ), mas não tem efeito (o backlit é 100% e não pode ser alterado). Eu também tentei registrar $DISPLAY e $USER e, no tempo de retorno, eles estão vazios. Então, meu palpite é que o script é executado muito cedo quando acordar do sono. Alguma dica?

    
por lviggiani 11.04.2014 / 08:35

3 respostas

14

Eu sei que essa é uma pergunta antiga, mas o arquivo de unidade a seguir funcionou para que eu executasse um script após sair do modo de suspensão:

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

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

[Install]
WantedBy=suspend.target

Acredito que é o After=suspend.target que o executa no currículo, em vez de quando o computador entra no modo de suspensão.

    
por 03.09.2015 / 17:09
6

Como uma alternativa para escrever e ativar um arquivo de unidade, você também pode colocar um script de shell (ou um link simbólico em seu script) em /lib/systemd/system-sleep/ .

Ele será chamado antes de dormir / hibernar e no horário de retomada.

Em man systemd-suspend.service :

Immediately before entering system suspend and/or hibernation systemd-suspend.service (and the other mentioned units, respectively) will run all executables in /usr/lib/systemd/system-sleep/ and pass two arguments to them. The first argument will be "pre", the second either "suspend", "hibernate", or "hybrid-sleep" depending on the chosen action. Immediately after leaving system suspend and/or hibernation the same executables are run, but the first argument is now "post". All executables in this directory are executed in parallel, and execution of the action is not continued until all executables have finished.

Teste com isso:

#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/

logger -t "test" "\
#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/

logger -t "test" "\%pre%=$0, \=$1, \=$2"
=$0, \=$1, \=$2"
    
por 13.01.2017 / 17:15
1

Acompanhamento da resposta de mivk, na qual eu evito usar um novo arquivo de unidade (veja minha pergunta aqui Como reagir a eventos de tampa do laptop? ). Aqui está minha solução; não é 100% simples ( suspiro ) porque o sistema não está estável quando sai do modo de suspensão:

Na minha caixa do Fedora 26 eu coloco um symlink aqui: /usr/lib/systemd/system-sleep/sleepyhead que aponta aqui: /root/bin/sleepyhead , que contém:

#!/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, \=$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, \=$2"

O script /root/bin/trackpoint segue. Note que o primeiro sono é crítico. O dispositivo é configurado toda vez que a tampa é aberta, portanto, não existe no início. Se eu tentar fazer algo além de dormir, o script "sleepyhead" demora muito para sair e meu ponteiro ficará congelado por pelo menos 60 segundos. Além disso, observe que você não pode colocar o script /root/bin/trackpoint em segundo plano em sleepyhead , acima. Se você fizer isso, o processo será eliminado quando sleepyhead sair.

#!/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"
    
por 15.09.2017 / 06:32