Améliorer mon script Bash

8

J'ai besoin d'améliorer mon script Bash pour qu'il fonctionne parfaitement sans problème. Ce script l'utilise ds4drvet il a des problèmes que je ne sais pas comment corriger.

Le premier problème est qu'il ne s'exécute pas ou ne fonctionne pas toujours lorsque le contrôleur est détecté, j'avais créé une règle udev pour cela, mais il n'est pas clair pourquoi il n'exécute pas toujours ce script lorsqu'il est détecté.

Deuxième problème, ds4drvne peut être exécuté qu'en tant que root, au lieu d'être exécuté en tant qu'utilisateur normal.

Troisième problème, je ne sais pas comment traiter correctement les fichiers de verrouillage PID une fois qu'ils ont été créés, de sorte que lorsque le processus PID n'existe plus, il supprime le fichier de verrouillage PID après. Il est difficile de trouver une documentation appropriée sur la façon d'utiliser les fichiers PID dans les scripts bash afin qu'il ne puisse y avoir qu'une seule instance en cours d'exécution.

Voici ma règle udev pour 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"

Je suis à peu près sûr que la règle udev devrait ressembler, les autorisations me semblent correctes car elles sont en lecture-écriture pour les utilisateurs de GROUP. Il semble y avoir un exemple d'un problème qui, une fois que mon script bash a été exécuté et que cette règle est définie pour s'exécuter automatiquement lorsque le périphérique du contrôleur est connecté, que certains jeux ne répondent plus comme si aucun périphérique du contrôleur n'est connecté lorsqu'il y en a un, c'est supposer pour agir /dev/js0mais agit à la /dev/js1place. Il peut souvent retourner cette erreur en particulier s'il n'est pas exécuté en tant que root;

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

et le script bash bien sûr; 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
la source
Pouvez-vous publier la règle udev?
Joe
@Joe Si vous aviez lu mon message, vous verriez qu'il est déjà là dans mon message principal.
Cette utilisation de /tmpest une faille de sécurité locale (suppression arbitraire de fichiers par rapport au script exécuté par l'utilisateur), mieux à utiliser /var/runou autre. Sinon, les fichiers PID ne seront qu'une solution moyenne avec des cas de bord et des pièges, selon la façon dont les choses se désagrègent.
thrig

Réponses:

1

Je suis préoccupé par 2 points

  • Fichiers PID que je ne connais pas, mais je suggère d'utiliser pgrepcomme solution de contournement.
  • ds4drvsemble un démon mais udevne prend en charge que les processus courts.

    RUN {type}

    ...

    Cela ne peut être utilisé que pour les tâches de premier plan à très court terme. L'exécution d'un processus d'événement pendant une longue période peut bloquer tous les autres événements pour ce périphérique ou un périphérique dépendant.

    Le démarrage de démons ou d'autres processus de longue durée n'est pas approprié pour udev; les processus bifurqués, détachés ou non, seront tués sans condition après la fin de la gestion de l'événement.

Faites une copie de ce script:

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown
user.dz
la source
1
Oui, ds4drvc'est un démon qui s'exécute en arrière-plan, mais problème avec mon script actuel, ce n'est pas de le laisser s'attacher /dev/js0mais plutôt de l'attacher à une nouvelle instance /dev/js1. Ma udevrègle devrait être de le faire fonctionner, /dev/js0mais il ne le fait pas correctement.Pour votre petit extrait, il ne fonctionne pas comme prévu, probablement à cause de ce double tuyau, car lorsque j'essaie de l'exécuter, il ne le fait pas une chose.
@ user94959, AFAIK il n'est pas possible de le corriger js0, le noyau effectuera un incrément pour chaque connexion de périphérique (même le même périphérique rebranché). Le mieux est de / ajouter une règle udev pour créer un lien symbolique. J'ai vérifié la documentation en amont, il suggère d'utiliser un fichier de service qui démarrera le démon au démarrage. Puis-je demander quel est l'inconvénient d'utiliser cette méthode?
user.dz
Je pense que le problème est /dev/js0le niveau utilisateur par défaut, mais comme le script me force à l'exécuter au niveau racine, il le rattache à la /dev/js1place, ce dont j'ai besoin est que le script s'exécute en tant qu'utilisateur normal au lieu de root. La raison pour laquelle cela m'oblige à exécuter en tant que root est que le fichier de configuration que j'ai ne s'appliquera pas du tout autrement. Le démon attend root, au lieu de l'utilisateur normal. Il devait y avoir une petite chose que vous pourriez faire pour le faire fonctionner au niveau normal de l'utilisateur, mais cela n'a pas fonctionné pour moi.