Запись в файл из команды udev RUN

1440
fuumind

Я работаю над созданием набора правил udev, который записывает в файл журнала каждый раз, когда вставляется определенный USB-накопитель. Мой набор правил, хранящийся в /etc/udev/rules.d /99-log-USB-drive.rules, в настоящее время содержит следующее:

# Skip if not the expected USB drive ENV!="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. 
1

3 ответа на вопрос

1
Kamil Maciorowski

Такие операторы, как |и >>т. Д., Означают что-то, находясь внутри оболочки, но когда /bin/echo 1 | …запускается sole, оболочки не существует, и |это просто еще один аргумент 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" … 
Это хорошо работает. Есть ли способ вставить литерал * в файл /home/myusername/udevtest.txt? Насколько я понимаю, в этом случае нет способа цитирования строки, переданной echo. Это правильно? Я бы предпочел не помещать ничего в сценарий. fuumind 6 лет назад 0
@fuumind Я не уверен, что понимаю проблему. Общие правила `sh` применяются в сценарии. Одинарные кавычки предотвращают сглаживание оболочки, поэтому это должно повторять буквальную звездочку: `echo '*'`. Перенаправьте его в файл, как вы хотите. Kamil Maciorowski 6 лет назад 0
0
IGI

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

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

0
fuumind

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

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

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

Похожие вопросы