Schreiben in eine Datei von einem udev-RUN-Befehl

1543
fuumind

Ich arbeite an der Erstellung eines udev-Regelsatzes, der jedes Mal, wenn ein bestimmtes USB-Laufwerk eingefügt wird, in eine Protokolldatei schreibt. Mein Regelsatz, gespeichert in /etc/udev/rules.d /99-log-USB-drive.rules, enthält derzeit Folgendes:

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

Die Befehle touch und chmod funktionieren wie erwartet, aber wenn ich versuche, in die Datei zu schreiben, bekomme ich nichts. Aktivieren des Debuggens für udev mithilfe von

udevadm control --log-priority=debug

macht die folgende Ausgabe in /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. 

beim Einstecken des USB-Laufwerks. Die Befehle sind zwar erfolgreich, aber die Ausgabe wird aus irgendeinem Grund nicht in die Datei geschrieben, den ich nicht sehen kann. Diese Frage zeigt an, dass das Schreiben in Dateien funktionieren sollte.

Nachtrag

Eine der Voraussetzungen für dieses Projekt ist, dass ich in der Lage sein muss, Sternchen ( *) in die Datei zu schreiben . Mit Hilfe der Informationen aus der ausgezeichneten Antwort von @Kamil Maciorowski kann ich in die Datei schreiben, aber ich kann nicht verhindern, dass die Shell das Sternchen erweitert.

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

schreibt beim Einfügen des USB-Laufwerks eine Auflistung des Inhalts des Root-Ordners in die Datei.

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

schreibt nichts in die Datei und rendert die folgende Ausgabe in /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. 

während

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

schreibt auch nichts in die Datei und rendert die folgende Ausgabe in /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 Antworten auf die Frage

1
Kamil Maciorowski

Operatoren wie |, >>usw. etwas bedeuten, während im Inneren einer Schale, aber wenn Sohle /bin/echo 1 | …ausgeführt wird, gibt es keine Schale und |ist nur ein weiteres Argument an echosich.

Um diese Operatoren verwenden zu können, müssen Sie eine Shell starten, die sie analysiert. Das sollte funktionieren:

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

Hier wählte ich echo(shell builtin) aus /bin/echo.

Alternativ können Sie einige Befehle (oder alle Befehle) in einem einzigen Shell-Skript (mit einem richtigen Shebang) sammeln und nur das Skript aus dem Regelsatz ausführen. Es wäre wie:

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

Vergessen Sie nicht, das Skript ausführbar zu machen. Dann in deinem Regelsatz:

… ACTION=="add", RUN+="/path/to/the/script" … 
Das funktioniert gut. Gibt es eine Möglichkeit, ein Literal * in die Datei /home/myusername/udevtest.txt zu kopieren? Soweit ich es verstehe, gibt es in diesem Fall keine Möglichkeit, die an echo übergebene Zeichenfolge zu zitieren. Ist das richtig? Ich würde es vorziehen, nichts in ein Skript einzufügen. fuumind vor 6 Jahren 0
Ich bin mir nicht sicher, ob ich das Problem verstehe. Im Skript gelten allgemeine `sh`-Regeln. Einfaches Anführungszeichen verhindert das Muscheln der Muscheln. Dies sollte ein literales Sternchen sein: `echo '*'`. Leiten Sie es wie gewünscht in eine Datei um. Kamil Maciorowski vor 6 Jahren 0
0
IGI

Wenn udevd ausgeführt wird, werden rootfs immer noch mit readonly-Optionen gemountet. Mit udev RUN können Sie also nichts in eine Datei ändern.

Hier sind die Bootvorgänge. init -> mount Kernel virtuelles Dateisystem (etc / run /) -> udev läuft -> mount all (/ etc / fstab)

0
fuumind

Beantwortung des Nachtrags meiner eigenen Frage: Escape the Stern funktioniert.

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

schreibt ein Sternchen in die Datei.