从 udev RUN 命令写入文件

fuu*_*ind 4 linux redirection pipe udev

我正在创建一个 udev 规则集,每次插入某个 USB 驱动器时都会写入日志文件。我的规则集存储在 中/etc/udev/rules.d /99-log-USB-drive.rules,当前包含以下内容:

# Skip if not the expected USB drive
ENV{ID_FS_UUID}!="SOMEUUID", GOTO="end"

# Try different ways of interacting with the file system
ACTION=="add", RUN+="/usr/bin/touch /home/myusername/udevtest.txt"
ACTION=="add", RUN+="/bin/chmod 664 /home/myusername/udevtest.txt"
ACTION=="add", RUN+="/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt"
ACTION=="add", RUN+="/bin/echo 2 >> /home/myusername/udevtest.txt"

# Exit
LABEL="end"
Run Code Online (Sandbox Code Playgroud)

touch 和 chmod 命令都按预期工作,但是当我尝试写入文件时,我什么也没得到。使用 udev 启用调试

udevadm control --log-priority=debug

将以下输出呈现为/var/log/syslog

Dec  3 18:00:49 Hostname systemd-udevd[9629]: starting '/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: '/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt'(out) '1 | /usr/bin/tee /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: Process '/bin/echo 1 | /usr/bin/tee /home/myusername/udevtest.txt' succeeded.
Dec  3 18:00:49 Hostname systemd-udevd[9630]: starting '/bin/echo 2 >> /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: '/bin/echo 2 >> /home/myusername/udevtest.txt'(out) '2 >> /home/myusername/udevtest.txt'
Dec  3 18:00:49 Hostname systemd-udevd[9612]: Process '/bin/echo 2 >> /home/myusername/udevtest.txt' succeeded.
Run Code Online (Sandbox Code Playgroud)

插入 USB 驱动器后。因此,命令成功,但由于某种我看不到的原因,输出未写入文件。这个问题表明写入文件应该有效。

附录

这个项目的要求之一是我需要能够将星号 ( *)写入文件。使用@Kamil Maciorowski 的优秀答案中的信息,我可以写入文件,但无法阻止 shell 扩展星号。

ACTION=="add", RUN+="/bin/sh -c 'echo * >> /home/myusername/udevtest.txt'"

插入 USB 驱动器后,将根文件夹的内容列表写入文件。

ACTION=="add", RUN+="/bin/sh -c 'echo "*" >> /home/myusername/udevtest.txt'"

不向文件写入任何内容并将以下输出呈现为/var/log/syslog

Jan  1 12:26:45 Hostname systemd-udevd[12359]: starting '/bin/sh -c 'echo '
Jan  1 12:26:45 Hostname systemd-udevd[12346]: '/bin/sh -c 'echo '(out) ''
Jan  1 12:26:45 Hostname systemd-udevd[12346]: Process '/bin/sh -c 'echo ' succeeded.
Run Code Online (Sandbox Code Playgroud)

尽管

ACTION=="add", RUN+="/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt'"

也不向文件写入任何内容并将以下输出呈现为/var/log/syslog

Jan  1 12:30:48 Hostname systemd-udevd[12477]: starting '/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt''
Jan  1 12:30:48 Hostname systemd-udevd[12464]: '/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt''(out) ''
Jan  1 12:30:48 Hostname systemd-udevd[12464]: Process '/bin/sh -c 'echo '*' >> /home/myusername/udevtest.txt'' succeeded.
Run Code Online (Sandbox Code Playgroud)

Kam*_*ski 8

诸如|, 之类的操作符>>在 shell 中意味着一些东西,但是当/bin/echo 1 | …运行唯一时,没有 shell 并且|只是echo它自身的另一个参数。

要使用这些运算符,您需要启动一个 shell 来解析它们。这应该有效:

…
ACTION=="add", RUN+="/bin/sh -c 'echo 1 | /usr/bin/tee /home/myusername/udevtest.txt'"
ACTION=="add", RUN+="/bin/sh -c 'echo 2 >> /home/myusername/udevtest.txt'"
…
Run Code Online (Sandbox Code Playgroud)

在这里,我选择了echo(shell builtin) 而不是/bin/echo.

或者,您可以在单个 shell 脚本(使用适当的 shebang)中收集几个命令(或所有命令),然后仅运行规则集中的脚本。它会是这样的:

#!/bin/sh

logfile="/home/myusername/udevtest.txt"

# /usr/bin should be in the defalut $PATH,
# so you probably don't need full paths to executables here

touch "$logfile"
chmod 664 "$logfile"
echo 1 | tee "$logfile"
echo 2 >> "$logfile"
Run Code Online (Sandbox Code Playgroud)

不要忘记使脚本可执行。然后在您的规则集中:

…
ACTION=="add", RUN+="/path/to/the/script"
…
Run Code Online (Sandbox Code Playgroud)