我试图实现的目标非常简单。
每当我将蓝牙设备连接到 Rspberry Pi 3(运行 Raspbian)时,脚本都会向日志文件添加一个条目。
很简单,因为困难的事情已经很好地工作了。
我已经配对了我的手机,每当连接或断开连接时都会触发以下规则:
pi@ras-pi:/ $ cat /etc/udev/rules.d/99-input.rules
SUBSYSTEM=="input",GROUP="input",MODE="0660"
KERNEL=="input[0-9]*",RUN+="/bin/bash -c 'echo TEST > /tmp/logfile.log'"
但是,结果始终是不存在的日志文件和返回码 1:
pi@ras-pi:/ $ journalctl -xe -u systemd-udevd
Sep 05 12:54:09 ras-pi systemd-udevd[2333]: Process '/bin/bash -c 'echo TEST > /tmp/logfile.log'' failed with exit code 1.
此时请注意,这是一个非常简化的示例。
最初我有一个独立的脚本,它被成功调用,旨在使用 echo 和输出重定向将一些信息写入日志文件。
我尝试了脚本的各种目标目录和位置进行测试,但结果都相同(失败,退出代码为 1)。
当我在当前 bash 会话中运行脚本时,它可以正常工作,就像顶部提到的命令一样:
pi@ras-pi:/ $ /bin/bash -c 'echo TEST > /tmp/logfile.log'
当我删除输出重定向时,它不会尝试写入文件,我不会在日志中收到错误消息,所以我猜脚本工作正常,这只是导致问题的重定向。原始示例的情况也是如此:
KERNEL=="input[0-9]*",RUN+="/bin/bash -c 'echo TEST'"
当然,我的第一个猜测是“权限”,所以这是 tmp 目录:
pi@ras-pi:/ $ ls -la /
(...)
drwxrwxrwt 10 root root 4096 Sep 5 12:54 tmp
(...)
这是我正在执行的脚本(只是为了完整):
pi@ras-pi:/ $ ls -la /usr/bin/bt_connect
-rwxr-xr-x 1 root root 110 Sep 5 11:36 /usr/bin/bt_connect
哦,顺便说一句:添加sudo
没有帮助:
pi@ras-pi:/ $ cat /etc/udev/rules.d/99-input.rules
SUBSYSTEM=="input",GROUP="input",MODE="0660"
KERNEL=="input[0-9]*",RUN+="/bin/bash -c 'sudo echo TEST > /tmp/logfile.log'"
这再次导致:
Sep 05 13:13:23 ras-pi systemd-udevd[2398]: Process '/bin/bash -c 'sudo echo TEST > /tmp/logfile.log'' failed with exit code 1.
有人可以帮我解决这个问题吗?
更新:至少我终于找到了一种通过不写入文件而是写入 /dev/kmsg 来生成一些调试输出的方法。这只是我的脚本中的一个示例:
echo $MSGCAT Path=$PATH >> /dev/kmsg
这样我发现脚本是在用户“root”下运行的,但直到现在我还没有找到为什么输出到任何文件都不起作用。
答案1
在 Raspibian 上,systemd-udevd 服务很可能使用 systemd 参数 ProtectSystem 运行。这意味着 udev 只能写入 /dev 目录中的文件。如果你跑
sudo systemctl edit systemd-udevd
它将在系统文本编辑器(很可能是 nano)中打开一个空的(除非您之前修改过)文本文件,您可以在其中更改 udev 服务的参数。按照https://www.freedesktop.org/software/systemd/man/systemd.exec.html你可能想添加
ReadWritePaths=/tmp
让您的原始脚本(写入 /tmp/logfile.log)正常工作。您还需要重新启动 udevd 才能使更改生效
sudo systemctl restart systemd-udevd