Escribir un servicio systemd para que se ejecute al reanudar

15

mi laptop Dell está sujeta a este error con el kernel 3.14. Como solución, escribí un script simple

/ usr / bin / brillo-arreglo:

#!/bin/bash

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

(y hecho ejecutable: chmod +x /usr/bin/brightness-fix)

y un servicio systemd que lo llama que se ejecuta al inicio:

/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

y habilitado: systemctl enable /etc/systemd/system/brightness-fix.service

Eso funciona de maravilla y puedo controlar el brillo de mi pantalla como lo desee. El problema se produce cuando la computadora portátil se reanuda después de ir al modo de suspensión (por ejemplo, al cerrar el borde de la computadora portátil): el control de brillo ya no funciona a menos que ejecute manualmente mi primer script anterior:/usr/bin/brightness-fix

¿Cómo puedo crear otro servicio systemd como el anterior para que se ejecute a la hora de reanudar?

EDITAR: Según los comentarios a continuación, he modificado mi brightness-fix.servicecomo este:

[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

También he agregado echo "$1 $2" > /home/luca/br.loga mi script para verificar si realmente se ejecuta. El script se ejecuta realmente también en resume ( post suspend) pero no tiene ningún efecto (la retroiluminación es del 100% y no se puede cambiar). También intenté iniciar sesión $DISPLAYy $USER, en el momento de reanudar, están vacíos. Entonces, supongo que el script se ejecuta demasiado temprano cuando se despierta. Alguna pista?

lviggiani
fuente
2
WantedBy=sleep.target...
jasonwryan
¡¿De Verdad?! ¿Es eso tan simple? :) ¿Puedo agregar 'sleep.target' a mi script anterior o debo crear un nuevo script de servicio systemd dedicado para él?
lviggiani
... de acuerdo con la documentación "Esta opción se puede usar más de una vez, o se puede dar una lista de nombres de unidades separadas por espacios". Lo intentaré ahora.
lviggiani
usted debe agregarlo a su archivo de servicio systemd existente (que, por cierto, es no un guión, es un archivo de configuración estática). y como nota al margen, el Estándar de Jerarquía del Sistema de Archivos establece que el lugar adecuado para colocar los scripts que usted mismo escribió /usr/local/binno es /usr/bin. ese directorio está reservado solo para el administrador de paquetes.
strugee
2
Creo que usar la sleep.targetunidad ejecutará la unidad cuando la computadora duerma, en lugar de cuando se reanude. Vea mi respuesta a continuación para obtener un archivo de unidad que funcionó para mí con un problema similar.
jat255

Respuestas:

18

Sé que esta es una pregunta antigua, pero el siguiente archivo de unidad me funcionó para ejecutar un script al reanudar desde el sueñ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

Creo que es lo After=suspend.targetque hace que se ejecute en el currículum, en lugar de cuando la computadora se duerme.

jat255
fuente
44
Funciona con After=suspend.target en Unidad y WantedBy=multi-user.target sleep.targeten Instalar .
Emmanuel
Estoy usando las siguientes unidades con éxito aquí en Ubuntu 16.04 (Loki elemental).
Naftuli Kay
7

Como alternativa a escribir y habilitar un archivo de unidad, también puede poner un script de shell (o un enlace simbólico a su script) /lib/systemd/system-sleep/.

Se llamará antes de dormir / hibernar, y a la hora de reanudar.

De man systemd-suspend.service:

Inmediatamente antes de ingresar al sistema, suspender y / o hibernar systemd-suspend.service (y las otras unidades mencionadas, respectivamente) ejecutarán todos los ejecutables en / usr / lib / systemd / system-sleep / y les pasarán dos argumentos. El primer argumento será "pre", el segundo ya sea "suspender", "hibernar" o "dormir híbrido" dependiendo de la acción elegida. Inmediatamente después de abandonar el sistema, suspender y / o hibernar, se ejecutan los mismos ejecutables, pero el primer argumento ahora es "post". Todos los ejecutables en este directorio se ejecutan en paralelo, y la ejecución de la acción no continúa hasta que todos los ejecutables hayan finalizado.

Pruébalo con esto:

#!/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
fuente
La página de manual que vincula menciona un archivo colocado, /usr/libpero todos sus ejemplos se refieren a archivos bajo/lib
qdii
@qdii: puede depender de la distribución y / o versión. En Debian 8 Jessie y Ubuntu 16.04, el system-sleepdirectorio parece estar /lib/systemd/y /usr/lib/systemdcontiene otras cosas.
mivk
1

Seguimiento de la respuesta de mivk, en la que evito muckear con un nuevo archivo de unidad (vea mi pregunta aquí ¿Cómo reaccionar ante los eventos de la tapa de la computadora portátil? ). Aquí está mi solución; no es 100% sencillo ( suspiro ) porque el sistema no es estable cuando sale del sueño:

En mi cuadro Fedora 26 pongo un enlace simbólico aquí: /usr/lib/systemd/system-sleep/sleepyheadque señala aquí: /root/bin/sleepyheadque 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"

El /root/bin/trackpointguión sigue. Tenga en cuenta que el primer sueño es crítico. El dispositivo se configura cada vez que se abre la tapa, por lo que no existe al principio. Si intento hacer algo más que dormir, el script "dormilón" tarda mucho tiempo en salir y mi puntero se congelará durante al menos 60 segundos. Además, tenga en cuenta que no puede poner el /root/bin/trackpointscript en segundo plano sleepyhead, arriba. Si lo hace, el proceso se cancelará cuando sleepyheadsalga.

#!/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
fuente
Muy bien organizado y documentado. ¡Te daría múltiples votos si pudiera!
MountainX-for-Monica