Memperbaiki skrip Bash saya

8

Saya perlu meningkatkan skrip Bash saya agar berjalan dengan sempurna tanpa masalah. Script ini digunakan ds4drvdi dalamnya dan memiliki beberapa masalah yang saya tidak yakin tentang cara memperbaikinya.

Masalah pertama adalah bahwa itu tidak selalu berjalan atau bekerja ketika controller terdeteksi, saya telah membuat aturan udev untuk itu tetapi tidak jelas mengapa itu tidak selalu menjalankan skrip ini ketika terdeteksi.

Masalah kedua, ds4drvhanya bisa dijalankan sebagai root saja, bukannya dijalankan sebagai pengguna biasa.

Masalah ketiga, saya tidak tahu cara yang tepat untuk berurusan dengan file kunci PID begitu mereka telah dibuat, sehingga ketika proses PID tidak ada lagi menghapus file kunci PID setelah. Sulit menemukan dokumentasi yang tepat tentang cara menggunakan file PID dalam skrip bash sehingga hanya ada 1 instance yang berjalan.

Inilah aturan udev saya untuk 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"

Saya cukup yakin seperti itulah seharusnya aturan udev, izin tampaknya benar bagi saya karena ini baca-tulis untuk pengguna GROUP. Tampaknya ada beberapa contoh masalah yang ketika skrip bash saya telah berjalan dan aturan ini diatur untuk berjalan secara otomatis ketika perangkat pengontrol terhubung, bahwa beberapa permainan menjadi tidak responsif seperti tidak ada perangkat pengontrol yang terhubung saat ada, itu anggaplah untuk bertindak /dev/js0tetapi sebaliknya bertindak /dev/js1sebagai gantinya. Ini mungkin sering mengembalikan kesalahan ini khususnya jika tidak dijalankan sebagai root;

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

dan skrip bash tentu saja; 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
sumber
Bisakah Anda memposting aturan udev?
Joe
@Joe Jika Anda telah membaca posting saya, Anda akan melihatnya sudah ada di postingan utama saya.
Penggunaan itu /tmpadalah kelemahan keamanan lokal (penghapusan file sewenang-wenang terhadap skrip yang dijalankan pengguna), lebih baik digunakan /var/runatau semacamnya. File PID sebaliknya hanya akan menjadi solusi biasa dengan case tepi dan gotcha, tergantung pada bagaimana hal-hal berantakan.
mulai

Jawaban:

1

Saya khawatir tentang 2 poin

  • File PID yang saya tidak kenal, tapi saya sarankan menggunakan pgrepsebagai solusi.
  • ds4drvtampaknya daemon tetapi udevhanya mendukung proses berjalan pendek.

    RUN {type}

    ...

    Ini hanya dapat digunakan untuk tugas latar depan yang sangat singkat. Menjalankan proses acara untuk jangka waktu yang lama dapat memblokir semua acara lebih lanjut untuk perangkat ini atau perangkat yang tergantung.

    Memulai daemon atau proses jangka panjang lainnya tidak sesuai untuk udev; proses bercabang, terlepas atau tidak, akan dibunuh tanpa syarat setelah penanganan acara selesai.

Buat salinan skrip itu:

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown
user.dz
sumber
1
Ya, ds4drvadalah daemon yang berjalan di latar belakang, tetapi masalah dengan skrip saya saat ini adalah tidak membiarkannya melampirkan /dev/js0tetapi malah melampirkan ke instance baru /dev/js1. udevAturan saya harus memperbaikinya agar berjalan /dev/js0tetapi tidak melakukannya dengan benar. Adapun cuplikan kecil Anda, itu tidak berfungsi sebagaimana dimaksud, mungkin karena pipa ganda itu, karena ketika saya mencoba menjalankannya, itu tidak berfungsi. hal.
@ user94959, AFAIK tidak dimungkinkan untuk memperbaikinya js0, kernel akan membuat peningkatan untuk setiap koneksi perangkat (bahkan perangkat yang sama dipasang kembali). Yang terbaik adalah / tambahkan aturan udev untuk membuat symlink. Saya memeriksa dokumentasi hulu, disarankan menggunakan file layanan yang akan memulai daemon saat boot. Bisakah saya bertanya apa yang tidak nyaman dalam menggunakan metode itu?
user.dz
Saya pikir masalahnya adalah /dev/js0tingkat pengguna default, tetapi karena skrip memaksa saya untuk menjalankannya pada level root, ia melampirkannya sebagai /dev/js1gantinya, yang saya butuhkan adalah skrip untuk dieksekusi sebagai pengguna normal dan bukan root. Alasannya memaksa saya untuk menjalankan sebagai root adalah karena file konfigurasi yang saya miliki tidak akan berlaku sama sekali sebaliknya. Daemon mengharapkan root, bukan pengguna normal. Seharusnya ada hal kecil yang bisa Anda lakukan untuk membuatnya berjalan pada tingkat pengguna normal, tetapi tidak berhasil bagi saya.