我需要改进我的 Bash 脚本,使其完美运行而不会出现问题。该脚本ds4drv
在其中使用,它有一些我不确定如何纠正的问题。
第一个问题是,当检测到控制器时,它并不总是运行或工作,我已经为其创建了一个 udev 规则,但不清楚为什么它在检测到控制器时并不总是运行该脚本。
第二个问题,ds4drv
只能允许以 root 身份运行,而不能以普通用户身份运行。
第三个问题,我不知道创建 PID 锁定文件后处理它们的正确方法,因此当 PID 进程不再存在时,它会删除 PID 锁定文件。很难找到有关如何在 bash 脚本中使用 PID 文件的正确文档,因此只能有 1 个正在运行的实例。
这是我的 ds4drv udev 规则: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"
我很确定 udev 规则应该是这样的,权限对我来说似乎是正确的,因为它对于 GROUP 用户是读写的。似乎确实存在一些问题,一旦我的 bash 脚本运行并且此规则设置为在连接控制器设备时自动运行,某些游戏会变得无响应,就像没有连接控制器设备一样,假设有采取行动/dev/js0
,但相反采取行动/dev/js1
。它可能经常返回此错误,特别是如果它不是以 root 身份执行的话;
OSError: [Errno 13] Permission denied: '/dev/input/event17'
当然还有 bash 脚本;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
答案1
我担心2点
- 我不熟悉 PID 文件,但我建议使用它
pgrep
作为解决方法。 ds4drv
似乎是一个守护进程,但udev
仅支持短时间运行的进程。运行{类型}
...
这只能用于运行时间非常短的前台任务。长时间运行事件进程可能会阻止该设备或从属设备的所有进一步事件。
启动守护进程或其他长时间运行的进程不适合 udev;分叉的进程,无论是否分离,都将在事件处理完成后被无条件终止。
复制该脚本:
#!/bin/bash
# DS4 Check Script
pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown