Melhorando o meu script Bash

8

Eu preciso melhorar meu script Bash para que ele seja executado sem problemas. Este script usa ds4drv e tem alguns problemas que não sei como corrigir.

A primeira questão é que nem sempre é executado ou funciona quando o controlador é detectado, eu criei uma regra do udev para ele, mas não está claro por que ele nem sempre executa esse script quando é detectado.

Segundo problema, ds4drv só pode ser executado como root apenas, em vez de ser executado como usuário normal.

Em terceiro lugar, eu não sei a maneira correta de lidar com os arquivos de bloqueio PID depois que eles foram criados, para que, quando o processo PID não existir mais, ele apague o arquivo de bloqueio PID depois. É difícil encontrar documentação adequada sobre como usar arquivos PID em scripts bash, de modo que só pode haver 1 instância em execução.

heres 'minha regra do 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"

Tenho certeza de que é assim que a regra do udev deve ser, as permissões parecem estar corretas para mim, já que é leitura-gravação para usuários do GROUP. Parece haver alguma instância de um problema que uma vez que meu script bash foi executado e esta regra está configurada para rodar automaticamente quando o dispositivo controlador está conectado, que alguns jogos não respondem como não há nenhum dispositivo controlador conectado quando existe, é suposto para agir em /dev/js0 , mas em vez disso, age em /dev/js1 . Muitas vezes, esse erro pode ser retornado, em particular, se não for executado como raiz;

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

e o script bash do curso; 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
    
por Rui F Ribeiro 30.01.2016 / 17:05

1 resposta

1

Estou preocupado com 2 pontos

  • Arquivos PID com os quais não estou familiarizado, mas sugiro usar pgrep como solução alternativa.
  • ds4drv parece um daemon, mas udev suporta apenas processos de execução curta.

    RUN{type}

    ...

    This can only be used for very short-running foreground tasks. Running an event process for a long period of time may block all further events for this or a dependent device.

    Starting daemons or other long-running processes is not appropriate for udev; the forked processes, detached or not, will be unconditionally killed after the event handling has finished.

Faça uma cópia desse script:

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown
    
por 04.02.2016 / 15:38