Мне нужно улучшить мой Bash-скрипт, чтобы он работал без проблем. Этот скрипт использует ds4drv
в нем, и есть некоторые проблемы, которые я не уверен, как исправить.
Первая проблема заключается в том, что он не всегда запускается или работает при обнаружении контроллера, я создал для него правило udev, но не ясно, почему он не всегда запускает этот скрипт при его обнаружении.
Вторая проблема, ds4drv
может быть разрешено запускать только от имени пользователя root, а не от имени обычного пользователя.
В-третьих, я не знаю, как правильно обращаться с файлами блокировки PID после их создания, поэтому, когда процесс PID больше не существует, он удаляет файл блокировки PID после. Трудно найти надлежащую документацию о том, как использовать PID-файлы в скриптах bash, чтобы был только 1 работающий экземпляр.
Вот мое правило udev для 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"
Я почти уверен, что именно так должно выглядеть правило udev, мне кажется, что права для него правильные, поскольку они доступны для чтения и записи для пользователей GROUP. Кажется, есть некоторый случай проблемы, когда мой скрипт bash запустился, и это правило настроено на автоматическое выполнение при подключении устройства контроллера, что некоторые игры перестают отвечать на запросы, например, если устройство контроллера не подключено, когда оно есть, предполагается, что действовать, /dev/js0
но вместо этого действует /dev/js1
вместо. Это может часто возвращать эту ошибку, в частности, если она не выполняется как root;
OSError: [Errno 13] Permission denied: '/dev/input/event17'
и скрипт bash, конечно; 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
/tmp
является локальным недостатком безопасности (произвольное удаление файлов против запускаемого пользователем скрипта), лучше использовать /var/run
или тому подобное. В противном случае PID-файлы будут только средним решением с крайними случаями и ошибками, в зависимости от того, как все развалится.