Улучшение моего Bash-скрипта


8

Мне нужно улучшить мой 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

Можете ли вы опубликовать правило Udev?
Джо

@Joe Если бы вы прочитали мой пост, вы бы увидели, что он уже есть в моем основном посте.

Такое использование /tmpявляется локальным недостатком безопасности (произвольное удаление файлов против запускаемого пользователем скрипта), лучше использовать /var/runили тому подобное. В противном случае PID-файлы будут только средним решением с крайними случаями и ошибками, в зависимости от того, как все развалится.
thrig

Ответы:


1

Я обеспокоен 2 пунктами

  • PID-файлы, с которыми я не знаком, но я бы предложил использовать в pgrepкачестве обходного пути.
  • ds4drvкажется демоном, но udevподдерживает только кратковременные процессы.

    RUN {тип}

    ...

    Это можно использовать только для очень коротких задач переднего плана. Выполнение обработки события в течение длительного периода времени может заблокировать все дальнейшие события для этого или зависимого устройства.

    Запуск демонов или других длительных процессов не подходит для udev; разветвленные процессы, отсоединенные или нет, будут безоговорочно уничтожены после завершения обработки события.

Сделайте копию этого скрипта:

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown

1
Да, ds4drvэто демон, который работает в фоновом режиме, но проблема с моим текущим сценарием заключается в том, что он не позволяет подключаться к нему, /dev/js0а вместо этого присоединяется к новому экземпляру /dev/js1. Моим udevправилом должно быть исправление, чтобы оно работало, /dev/js0но оно работает неправильно. Что касается вашего небольшого фрагмента, он не работает должным образом, возможно, из-за этого двойного канала, потому что когда я пытаюсь запустить его, он не работает вещь.

@ user94959, AFAIK исправить это невозможно js0, ядро ​​будет делать приращение для каждого соединения с устройством (даже если переподключено одно и то же устройство). Лучше всего добавить / добавить правило udev для создания символической ссылки. Я проверил исходную документацию, она предлагает использовать служебный файл, который запустит демон при загрузке. Могу я спросить, что неудобно при использовании этого метода?
user.dz

Я думаю, что проблема заключается в том, что /dev/js0это уровень пользователя по умолчанию, но поскольку скрипт заставляет меня запускать его на корневом уровне, он присоединяется к нему /dev/js1, а мне нужно, чтобы скрипт выполнялся как обычный пользователь, а не как root. Причина, по которой это заставляет меня работать от имени root, заключается в том, что файл конфигурации, который у меня есть, не будет применяться вообще. Демон ожидает root, а не обычный пользователь. Предполагалось, что вы могли бы кое-что сделать, чтобы он работал на нормальном уровне пользователя, но у меня это не сработало.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.