Mein Bash-Skript verbessern

8

Ich muss mein Bash-Skript verbessern, damit es fehlerfrei und ohne Probleme ausgeführt wird. Dieses Skript verwendet ds4drves und es gibt einige Probleme, deren Korrektur ich nicht sicher bin.

Das erste Problem ist, dass es nicht immer ausgeführt wird oder funktioniert, wenn der Controller erkannt wird. Ich habe eine udev-Regel dafür erstellt, aber es ist nicht klar, warum dieses Skript nicht immer ausgeführt wird, wenn es erkannt wird.

Das zweite Problem ds4drvkann nur als Root ausgeführt werden, anstatt als normaler Benutzer.

Drittes Problem: Ich kenne den richtigen Umgang mit PID-Sperrdateien nach deren Erstellung nicht. Wenn der PID-Prozess nicht mehr vorhanden ist, wird die PID-Sperrdatei danach gelöscht. Es ist schwierig, eine angemessene Dokumentation zur Verwendung von PID-Dateien in Bash-Skripten zu finden, sodass nur eine Instanz ausgeführt werden kann.

Hier ist meine udev-Regel für 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"

Ich bin mir ziemlich sicher, dass die udev-Regel so aussehen sollte. Berechtigungen scheinen mir korrekt zu sein, da sie für GROUP-Benutzer gelesen und geschrieben werden. Es scheint ein Problem zu geben, bei dem, sobald mein Bash-Skript ausgeführt wurde und diese Regel automatisch ausgeführt wird, wenn das Controller-Gerät angeschlossen ist, einige Spiele nicht mehr reagieren, da kein Controller-Gerät angeschlossen ist, wenn es vorhanden ist zu handeln, /dev/js0sondern stattdessen zu handeln /dev/js1. Dieser Fehler kann häufig zurückgegeben werden, insbesondere wenn er nicht als root ausgeführt wird.

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

und das Bash-Skript natürlich; 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
quelle
Können Sie die udev-Regel posten?
Joe
@ Joe Wenn du meinen Beitrag gelesen hättest, würdest du sehen, dass er bereits in meinem Hauptbeitrag enthalten ist.
Diese Verwendung von /tmpist eine lokale Sicherheitslücke (willkürliches Löschen von Dateien gegen Benutzer, die ein Skript ausführen), besser zu verwenden /var/runoder dergleichen. Ansonsten sind PID-Dateien nur eine mittelmäßige Lösung mit Randfällen und Fallstricken, je nachdem, wie die Dinge auseinanderfallen.
Thrig

Antworten:

1

Ich mache mir Sorgen um 2 Punkte

  • PID-Dateien, mit denen ich nicht vertraut bin, die ich jedoch pgrepals Problemumgehung empfehlen würde .
  • ds4drvscheint ein Daemon zu sein, udevunterstützt aber nur kurz laufende Prozesse.

    RUN {Typ}

    ...

    Dies kann nur für sehr kurz laufende Vordergrundaufgaben verwendet werden. Das Ausführen eines Ereignisprozesses über einen längeren Zeitraum kann alle weiteren Ereignisse für dieses oder ein abhängiges Gerät blockieren.

    Das Starten von Daemons oder anderen lang laufenden Prozessen ist für udev nicht geeignet. Die getrennten oder nicht getrennten gegabelten Prozesse werden nach Abschluss der Ereignisbehandlung bedingungslos beendet.

Erstellen Sie eine Kopie dieses Skripts:

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown
user.dz
quelle
1
Ja, es ds4drvhandelt sich um einen Daemon, der im Hintergrund ausgeführt wird. Bei meinem aktuellen Skript besteht jedoch kein Problem darin /dev/js0, dass eine Verbindung zu einer neuen Instanz hergestellt /dev/js1wird. Meine udevRegel sollte sein, dass es so ausgeführt wird /dev/js0, dass es ausgeführt wird, aber es funktioniert nicht richtig. Was Ihr kleines Snippet betrifft, funktioniert es nicht wie beabsichtigt, wahrscheinlich aufgrund dieser Doppelpipe, denn wenn ich versuche, es auszuführen, funktioniert es nicht ein Ding.
@ user94959, AFAIK Es ist nicht möglich js0, das Problem zu beheben . Der Kernel führt für jede Geräteverbindung ein Inkrement durch (auch wenn dasselbe Gerät neu angeschlossen wurde). Am besten fügen Sie eine udev-Regel hinzu, um einen Symlink zu erstellen. Ich habe die Upstream-Dokumentation überprüft. Es wird empfohlen, eine Servicedatei zu verwenden, mit der der Dämon beim Booten gestartet wird. Könnte ich fragen, was bei der Verwendung dieser Methode unpraktisch ist?
user.dz
Ich denke, das Problem ist, dass /dev/js0es sich um die Standardbenutzerebene handelt. Da das Skript mich jedoch zwingt, es auf Stammebene /dev/js1auszuführen , hängt es stattdessen an das Skript an. Ich muss es also als normalen Benutzer anstelle von root ausführen. Der Grund, warum ich gezwungen bin, als root zu arbeiten, ist, dass die Konfigurationsdatei, die ich habe, sonst überhaupt nicht angewendet wird. Der Dämon erwartet root anstelle des normalen Benutzers. Es gab vermutlich eine Kleinigkeit, die Sie tun könnten, um es auf normaler Benutzerebene laufen zu lassen, aber es hat bei mir nicht funktioniert.