Cải thiện tập lệnh Bash của tôi


8

Tôi cần cải thiện tập lệnh Bash của mình để nó chạy hoàn hảo mà không gặp vấn đề gì. Kịch bản này sử dụng ds4drvtrong nó và nó có một số vấn đề mà tôi không chắc về cách sửa.

Vấn đề đầu tiên là nó không luôn chạy hoặc hoạt động khi bộ điều khiển được phát hiện, tôi đã tạo quy tắc udev cho nó nhưng không rõ tại sao nó không luôn chạy tập lệnh này khi phát hiện ra.

Vấn đề thứ hai, ds4drvchỉ có thể được phép chạy dưới quyền root, thay vì được chạy như người dùng bình thường.

Vấn đề thứ ba, tôi không biết cách xử lý thích hợp với các tệp khóa PID sau khi chúng được tạo, để khi quá trình PID không còn tồn tại, nó sẽ xóa tệp khóa PID sau đó. Thật khó để tìm tài liệu phù hợp về cách sử dụng các tệp PID trong tập lệnh bash để chỉ có thể có 1 phiên bản đang chạy.

Đây là quy tắc udev của tôi cho 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"

Tôi khá chắc chắn rằng đó là quy tắc udev sẽ như thế nào, các quyền dường như là chính xác đối với tôi vì nó đọc-ghi cho người dùng GROUP. Dường như có một số trường hợp xảy ra khi kịch bản bash của tôi chạy và quy tắc này được đặt tự động khi thiết bị điều khiển được kết nối, một số trò chơi trở nên không phản hồi như không có thiết bị điều khiển nào được kết nối khi có, giả sử để hành động /dev/js0nhưng thay vào đó hành động /dev/js1thay thế. Nó thường có thể trả về lỗi này cụ thể nếu nó không được thực thi như root;

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

và kịch bản bash tất nhiên; 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

Bạn có thể đăng quy tắc udev?
Joe

@Joe Nếu bạn đã đọc bài viết của tôi, bạn sẽ thấy nó đã có trong bài viết chính của tôi.

Việc sử dụng đó /tmplà một lỗ hổng bảo mật cục bộ (xóa tệp tùy ý đối với tập lệnh đang chạy của người dùng), tốt hơn để sử dụng /var/runhoặc như vậy. Các tập tin PID khác sẽ chỉ là một giải pháp tương tự với các trường hợp cạnh và gotchas, tùy thuộc vào cách mọi thứ sụp đổ.
thrig

Câu trả lời:


1

Tôi quan tâm đến 2 điểm

  • Các tệp PID mà tôi không quen thuộc, nhưng tôi khuyên bạn nên sử dụng pgrepnhư một cách giải quyết.
  • ds4drvcó vẻ như một daemon nhưng udevchỉ hỗ trợ các quá trình chạy ngắn.

    CHẠY {loại}

    ...

    Điều này chỉ có thể được sử dụng cho các tác vụ nền trước chạy rất ngắn. Chạy một quy trình sự kiện trong một thời gian dài có thể chặn tất cả các sự kiện tiếp theo cho thiết bị này hoặc một thiết bị phụ thuộc.

    Bắt đầu trình nền hoặc các quá trình chạy dài khác không phù hợp với udev; các quá trình rẽ nhánh, tách ra hoặc không, sẽ bị giết vô điều kiện sau khi xử lý sự kiện kết thúc.

Tạo một bản sao của tập lệnh đó:

#!/bin/bash
# DS4 Check Script

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

1
Vâng, ds4drvlà một trình nền chạy trong nền, nhưng vấn đề với tập lệnh hiện tại của tôi là nó không cho phép nó đính kèm /dev/js0mà thay vào đó, gắn vào một phiên bản mới /dev/js1thay thế. udevQuy tắc của tôi là sửa nó để chạy /dev/js0nhưng nó không hoạt động chính xác. Đối với đoạn mã nhỏ của bạn, nó không hoạt động như dự định, có thể là do đường ống đôi đó, vì khi tôi cố chạy nó, nó không làm một vật.

@ user94959, AFAIK không thể sửa nó js0, kernel sẽ tăng thêm cho mỗi kết nối thiết bị (ngay cả cùng một thiết bị được thay thế). Tốt nhất là / thêm quy tắc udev để tạo liên kết tượng trưng. Tôi đã kiểm tra tài liệu ngược dòng, nó đề nghị sử dụng tệp dịch vụ sẽ khởi động trình nền khi khởi động. Tôi có thể hỏi những gì bất tiện trong việc sử dụng phương pháp đó?
user.dz

Tôi nghĩ vấn đề là /dev/js0cấp độ người dùng mặc định, nhưng vì tập lệnh buộc tôi phải chạy nó ở cấp độ gốc, nên nó gắn nó vào /dev/js1thay vào đó, điều tôi cần là để tập lệnh thực thi như người dùng bình thường thay vì root. Lý do nó buộc tôi phải chạy bằng root là vì tệp cấu hình tôi hoàn toàn không áp dụng. Trình nền mong đợi root, thay vì người dùng bình thường. Có thể có một điều nhỏ bạn có thể làm để làm cho nó chạy ở mức người dùng bình thường, nhưng nó không hoạt động với tôi.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.