Preciso melhorar meu script Bash para que ele funcione perfeitamente sem problemas. Este script usa ds4drv
nele 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, ds4drv
só 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/js0
mas 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
fonte
/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/run
ou 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.Respostas:
Estou preocupado com 2 pontos
pgrep
como solução alternativa.ds4drv
parece um daemon, masudev
suporta apenas processos de execução curta.Faça uma cópia desse script:
fonte
ds4drv
é um daemon que é executado em segundo plano, mas o problema com o meu script atual não é deixá-lo anexar,/dev/js0
mas sim anexar a uma nova instância/dev/js1
. A minhaudev
regra deve ser corrigi-lo para executar,/dev/js0
mas 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.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?/dev/js0
o 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.