1

Я работаю над созданием набора правил 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"

Обе команды 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.

после вставки USB-накопителя. Итак, команды выполняются успешно, но вывод не записывается в файл по какой-то причине, которую я не вижу. Этот вопрос указывает на то, что запись в файлы должна работать.

добавление

Одним из требований для этого проекта является то, что мне нужно иметь возможность записывать звездочки (*) в файл. Используя информацию из превосходного ответа @Kamil Maciorowski, я могу записать файл, но не могу предотвратить расширение звездочки в оболочке.

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.

в то время как

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.

3 ответа3

1

Операторы как | , >> и т.д. означают что-то, находясь внутри оболочки, но когда единственный /bin/echo 1 | … запускается, нет оболочки и | это просто еще один аргумент в пользу echo .

Чтобы использовать эти операторы, вам нужно запустить оболочку, которая будет их анализировать. Это должно работать:

…
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'"
…

Здесь я выбрал echo (встроенную оболочку) вместо /bin/echo .

В качестве альтернативы вы можете собрать несколько команд (или все они) в один сценарий оболочки (с надлежащим шебангом) и запустить только сценарий из набора правил. Это было бы как:

#!/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"

Не забудьте сделать скрипт исполняемым. Тогда в вашем наборе правил:

…
ACTION=="add", RUN+="/path/to/the/script"
…
0

Отвечая на добавление моего собственного вопроса: «Звездочка работает».

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

записывает звездочку в файл

0

Когда udevd начинает работать, rootfs все еще монтируется с опциями только для чтения. Таким образом, вы не можете ничего изменить в файл с ключом RUN udev.

Вот процессы загрузки. init -> монтировать виртуальную файловую систему ядра (и т. д. /run /) -> запуск udev -> монтировать все (/etc /fstab)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .