Ersetzen \0
durch \n
:
eval "export $(tr -s \\0 \\n </proc/$(pgrep -u $LOGNAME -x gnome-session)/environ|grep DBUS_SESSION_BUS_ADDRESS)";/usr/bin/notify-send 'Hello world!'
Ich verwende einen postfix
mit einem kommerziellen SMTP-Server verknüpften cron
Job, um ihren Besitzern im Falle eines Fehlers / einer Warnung eine E-Mail zu senden. Dies ist ein Arch-Setup mit einer Box.
postfix
funktioniert. Tut es auch cronie
. Obwohl der einfachste aller Cron-Jobs ausgelöst wird, erhalte ich bei jeder Ausführung eine E-Mail vom Cron-Daemon, die lautet:
/ bin / sh: warning: Befehlsersetzung: Null-Byte in Eingabe ignoriert.
Die Cron-Regel, die als Test jede Minute ausgeführt werden soll, lautet:
MAILTO=MYUSERNAME@LOCALHOSTNAME * * * * * eval "export $(grep -Ez DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";/home/USERNAME/test
und die ausführbare Datei ~ / test lautet im Wesentlichen:
#!/bin/bash /usr/bin/notify-send 'Hello world!' --icon=dialog-information
Ich verstehe, dass grep -Ez [...]
ein Null-Byte eingeführt wird, wie es durch seine Ausgabe mit ungewöhnlichen Zeichen erforderlich wird.
Mein Spielzeugbeispiel würde richtig funktionieren, wenn diese Warnung nicht bei jeder Ausführung per E-Mail an USERNAME gesendet würde. Wie werde ich das los?
Ersetzen \0
durch \n
:
eval "export $(tr -s \\0 \\n </proc/$(pgrep -u $LOGNAME -x gnome-session)/environ|grep DBUS_SESSION_BUS_ADDRESS)";/usr/bin/notify-send 'Hello world!'
Nach einigen Nachforschungen stellt sich heraus, dass grep -Ez [...]
dies in einem Cron-Job nicht der richtige Weg ist.
/proc/[pid]/environ
In Linux hat OS die Eigenart, dass das Null-Byte das Datensatztrennzeichen ist, sodass sein Inhalt bei der Ausgabe in stdout wie eine einzelne Zeile "aussieht", dh ohne EOL-Zeichen:
$ cat -v /proc/$(pgrep -u $LOGNAME gnome-session)/environ LC_MEASUREMENT=en_IE.UTF-8^@LC_PAPER=en_IE.UTF-8^@LC_MONETARY=en_IE.UTF-8^@LANG=en_US.UTF-8^@GDM_LANG=en_US.UTF-8^@DISPLAY=:1^@USERNAME=USERNAME^@MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins^@XDG_VTNR=2^@XDG_SESSION_ID=2^@USER=USERNAME^@DESKTOP_SESSION=gnome^@PWD=/home/USERNAME^@HOME=/home/USERNAME^@XDG_SESSION_TYPE=x11^@XDG_SESSION_DESKTOP=gnome^@LC_NUMERIC=en_IE.UTF-8^@MAIL=/var/spool/mail/USERNAME^@WINDOWPATH=2^@SHELL=/bin/bash^@XDG_CURRENT_DESKTOP=GNOME^@XDG_SEAT=seat0^@SHLVL=0^@GDMSESSION=gnome^@LOGNAME=USERNAME^@DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus^@XDG_RUNTIME_DIR=/run/user/1000^@XAUTHORITY=/run/user/1000/gdm/Xauthority^@PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl^@LC_TIME=en_IE.UTF-8^@
In dem obigen habe ich cat
mit der -v
Flagge verwendet, um keine Bytes anzugeben.
Die Lösung besteht also darin, nach dem Muster zu suchen, "DBUS_SESSION_BUS_ADDRESS"
während Null-Bytes erkannt werden. awk
und gawk
beide tun dies, obwohl es nicht portabel ist, indem sie das Datensatztrennzeichen in den Hexadezimalcode für das nul-Byte ändern:\x00
$ awk -F 'BEGIN /DBUS_SESSION_BUS_ADDRESS/' /proc/$(pgrep -u $LOGNAME gnome-session)/environ DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
Das erzeugt tatsächlich eine saubere Ausgabe ohne nul Bytes und wird von sehr gut angenommen cron
. Es wird keine Warnung ausgegeben und keine E-Mail gesendet.