Melhorando meu script Bash

8

Preciso melhorar meu script Bash para que ele funcione perfeitamente sem problemas. Este script usa ds4drvnele e tem alguns problemas que não tenho certeza sobre 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, ds4drvsó pode ser executado como root, em vez de ser executado como usuário normal.

Terceiro problema, não sei a maneira correta de lidar com os arquivos de bloqueio do PID depois que eles foram criados, para que, quando o processo do PID não exista mais, ele apague o arquivo de bloqueio do PID. É difícil encontrar a documentação adequada sobre como usar arquivos PID em scripts bash, para que possa haver apenas uma instância em execução.

aqui está 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 que é assim que deve ser a regra do udev, as permissões parecem corretas para mim, pois é de leitura e gravação para usuários do GROUP. Parece haver algum exemplo de problema que, uma vez que meu script bash é executado e esta regra é definida para ser executada automaticamente quando o dispositivo controlador está conectado, que alguns jogos ficam sem resposta, como se não houvesse um dispositivo controlador conectado quando houver, é suposto para agir, /dev/js0mas em vez disso age /dev/js1. Geralmente, esse erro pode retornar, em particular, se não for executado como root;

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

e o script bash, é claro; 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
fonte
Você pode postar a regra do udev?
21316 Joe Joe
@ Joe Se você tivesse lido meu post, veria que ele já está lá no meu post principal.
Esse uso de /tmpé uma falha de segurança local (exclusão arbitrária de arquivos contra o script em execução do usuário), melhor para usar /var/runou algo assim. Caso contrário, os arquivos PID serão apenas uma solução mais ou menos com casos extremos e dicas, dependendo de como as coisas desmoronam.
thrig

Respostas:

1

Estou preocupado com 2 pontos

  • Arquivos PID com os quais não estou familiarizado, mas sugiro usar pgrepcomo solução alternativa.
  • ds4drvparece um daemon, mas udevsuporta apenas processos de execução curta.

    EXECUTAR {type}

    ...

    Isso pode ser usado apenas para tarefas de primeiro plano de execução muito curta. A execução de um processo de evento por um longo período de tempo pode bloquear todos os outros eventos deste ou de um dispositivo dependente.

    Iniciar daemons ou outros processos de longa execução não é apropriado para o udev; os processos bifurcados, desanexados ou não, serão eliminados incondicionalmente após o término da manipulação do evento.

Faça uma cópia desse script:

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown
user.dz
fonte
1
Sim, ds4drvé um daemon que é executado em segundo plano, mas o problema com o meu script atual não é deixá-lo anexar, /dev/js0mas sim anexar a uma nova instância /dev/js1. A minha udevregra deve ser corrigi-lo para executar, /dev/js0mas não está funcionando corretamente. Quanto ao seu pequeno trecho, ele não funciona conforme o esperado, provavelmente por causa desse tubo duplo, porque quando eu tento executá-lo, ele não funciona. uma coisa.
@ user94959, AFAIK não é possível corrigi-lo js0, o kernel fará um incremento para cada conexão de dispositivo (mesmo o mesmo dispositivo reconectado). O melhor é / adicionar uma regra do udev para criar um link simbólico. Verifiquei a documentação upstream, ela sugere o uso do arquivo de serviço que iniciará o daemon na inicialização. Posso perguntar qual é o inconveniente em usar esse método?
User.dz
Acho que o problema é /dev/js0o nível de usuário padrão, mas, como o script está me forçando a executá-lo no nível raiz, ele o anexa /dev/js1, o que eu preciso é que o script seja executado como usuário normal em vez de raiz. A razão pela qual me obriga a executar como root é porque o arquivo de configuração que eu tenho não será aplicado de outra forma. O daemon espera raiz, em vez de usuário normal. Supõe-se que você poderia fazer algo para executá-lo no nível normal do usuário, mas não funcionou para mim.