Mejorando mi script Bash

8

Necesito mejorar mi script Bash para que funcione sin problemas sin problemas. Este script lo utiliza ds4drvy tiene algunos problemas que no estoy seguro de cómo corregir.

El primer problema es que no siempre se ejecuta o no funciona cuando se detecta el controlador, había creado una regla udev para él, pero no está claro por qué no siempre ejecuta este script cuando se detecta.

Segundo problema, ds4drvsolo se puede permitir que se ejecute solo como root, en lugar de ejecutarse como usuario normal.

Tercer problema, no conozco la forma correcta de tratar con los archivos de bloqueo PID una vez que se han creado, de modo que cuando el proceso PID ya no existe, elimina el archivo de bloqueo PID después. Es difícil encontrar la documentación adecuada sobre cómo usar los archivos PID en los scripts de bash, por lo que solo puede haber una instancia en ejecución.

aquí está mi regla de udev para ds4drv: 50-ds4drv.rules

KERNEL=="uinput", GROUP="users", MODE="0666"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="05c4", GROUP="users", MODE="0
666"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", KERNELS=="0005:054C:05C4.*", GROUP="users" MODE="0666"
ACTION=="add", SUBSYSTEM="usb", ATTRS{idProduct}=="054c", RUN+="/home/user/scripts/ds4check.sh", GROUP="users"
, MODE="0666"

Estoy bastante seguro de que así es como debería ser la regla de udev, los permisos parecen ser correctos para mí, ya que es de lectura y escritura para usuarios de GROUP. Parece haber una instancia de un problema que una vez que mi script bash se ha ejecutado y esta regla está configurada para ejecutarse automáticamente cuando se conecta el dispositivo controlador, que algunos juegos dejan de responder como si no hubiera ningún dispositivo controlador conectado cuando lo hay, se supone para actuar /dev/js0pero en su lugar actúa en su /dev/js1lugar. A menudo puede devolver este error en particular si no se ejecuta como root;

OSError: [Errno 13] Permission denied: '/dev/input/event17'

y el guión bash, por supuesto; ds4check.sh

#!/bin/bash
# DS4 Check Script

pidfile=/tmp/ds4drv.pid

# check if process is already running
for pid in $(pidof -x /home/user/scripts/ds4check.sh $pidfile); do
    if [ $pid != $$ ]; then
      echo "[$(date)] : ds4check.sh : Proccess is already running with PID $pid" >> /home/user/.cache/ds4drv.log
      exit 1
# if not running then run and apply config
      else  ( ds4drv --hidraw --config /home/user/.config/ds4drv.conf )

      exit 0
    fi
done

# remove PID file on exit... hopefully
trap "srm -rv -- '$pidfile'" EXIT >> /home/user/.cache/ds4drv.log
Rui F Ribeiro
fuente
¿Puedes publicar la regla de udev?
Joe
@ Joe Si hubieras leído mi publicación, verías que ya está allí en mi publicación principal.
Ese uso de /tmpes una falla de seguridad local (eliminación arbitraria de archivos contra el script que ejecuta el usuario), mejor usar /var/runo tal. De lo contrario, los archivos PID solo serán una solución regular con casos extremos y problemas, dependiendo de cómo se desmoronen las cosas.
thrig

Respuestas:

1

Estoy preocupado por 2 puntos

  • Archivos PID con los que no estoy familiarizado, pero sugeriría usarlos pgrepcomo solución alternativa.
  • ds4drvparece un demonio pero udevsolo admite procesos de ejecución cortos.

    EJECUTAR {tipo}

    ...

    Esto solo se puede utilizar para tareas en primer plano de muy corta duración. La ejecución de un proceso de evento durante un largo período de tiempo puede bloquear todos los eventos adicionales para este o un dispositivo dependiente.

    Iniciar daemons u otros procesos de larga duración no es apropiado para udev; los procesos bifurcados, separados o no, se eliminarán incondicionalmente una vez que haya finalizado el manejo del evento.

Haga una copia de ese script:

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown
user.dz
fuente
1
Sí, ds4drves un demonio que se ejecuta en segundo plano, pero el problema con mi script actual es que no permite que se adjunte /dev/js0sino que se conecta a una nueva instancia /dev/js1. Mi udevregla debería ser arreglarlo para que se ejecute, /dev/js0pero no lo está haciendo correctamente. En cuanto a su pequeño fragmento, no funciona según lo previsto, probablemente debido a ese doble tubo, porque cuando trato de ejecutarlo, no funciona una cosa.
@ user94959, AFAIK no es posible arreglarlo js0, el kernel hará un incremento para cada conexión de dispositivo (incluso el mismo dispositivo enchufado). Lo mejor es / agregar una regla udev para crear un enlace simbólico. Revisé la documentación ascendente, sugiere usar el archivo de servicio que iniciará el demonio en el arranque. ¿Puedo preguntar cuál es el inconveniente de usar ese método?
user.dz
Creo que el problema es que /dev/js0es el nivel de usuario predeterminado, pero dado que el script me obliga a ejecutarlo en el nivel raíz, lo adjunta en su /dev/js1lugar, lo que necesito es que el script se ejecute como usuario normal en lugar de root. La razón por la que me obliga a ejecutar como root es porque el archivo de configuración que tengo no se aplicará de ninguna otra manera. El demonio espera root, en lugar de usuario normal. Se suponía que había algo pequeño que podría hacer para que se ejecute a nivel de usuario normal, pero no funcionó para mí.