改善我的Bash脚本


8

我需要改进我的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

您可以发布udev规则吗?

@Joe如果您阅读了我的文章,您会发现它已经存在于我的主要文章中。

的使用/tmp是一种本地安全漏洞(针对用户正在运行的脚本,任意删除文件),/var/run或者更好地使用。否则,PID文件只能解决边缘情况和陷阱,具体取决于情况如何。
thrig

Answers:


1

我担心2分

  • 我不熟悉的PID文件,但我建议使用pgrep作为替代方法。
  • ds4drv似乎是一个守护进程,但udev仅支持短期运行的进程。

    运行{类型}

    ...

    这只能用于运行时间非常短的前台任务。长时间运行事件过程可能会阻止此设备或从属设备的所有其他事件。

    启动守护程序或其他长时间运行的进程不适合udev;事件处理完成后,分叉的进程(无论是否分离)将无条件终止。

复制该脚本:

#!/bin/bash
# DS4 Check Script

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

1
是的,ds4drv是一个在后台运行的守护程序,但是我当前的脚本存在问题,它不是让它附加到/dev/js0而是附加到新实例上/dev/js1。我的udev规则应该是将其修复以在其上运行,/dev/js0但操作不正确。至于您的小片段,它无法按预期运行,可能是因为有双重管道,因为当我尝试运行它时,它没有做一个东西。

@ user94959,AFAIK不可能将其修复为js0,内核将为每个设备连接(甚至重新插入相同的设备)增加一个增量。最好是/ udev规则创建一个符号链接。我检查了上游文档,它建议使用将在引导时启动守护程序的服务文件。请问使用该方法有何不便之处?
user.dz

我认为问题在于/dev/js0默认用户级别,但是由于脚本迫使我在根级别上运行它,因此它附加了它/dev/js1,我需要的是脚本以普通用户(而不是root)身份执行。之所以迫使我以root用户身份运行,是因为我原本不会应用的配置文件。守护程序需要root用户,而不是普通用户。可以做一些事情使它在普通用户级别运行,但是对我来说不起作用。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.