Заменить \0
на \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!'
Я использую postfix
связанный с коммерческим сервером smtp для cron
рабочих мест, чтобы послать их владельцам электронную почту в случае ошибки / предупреждения. Это один из параметров настройки Arch.
postfix
работает. Так и делает cronie
. Но хотя самая простая из всех задач cron срабатывает, я получаю электронное письмо от демона cron при каждом выполнении, которое гласит:
/ bin / sh: предупреждение: подстановка команд: игнорируется нулевой байт при вводе.
Правило cron, которое нужно запускать каждую минуту в качестве теста:
MAILTO=MYUSERNAME@LOCALHOSTNAME * * * * * eval "export $(grep -Ez DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";/home/USERNAME/test
и исполняемый файл ~ / test в основном:
#!/bin/bash /usr/bin/notify-send 'Hello world!' --icon=dialog-information
Я понимаю, что grep -Ez [...]
вводит нулевой байт, что необходимо при его выводе с некоторыми необычными символами.
Мой игрушечный пример работал бы правильно, если бы не это конкретное предупреждение, отправляемое по электронной почте пользователю USERNAME при каждом выполнении. Как мне избавиться от этого?
Заменить \0
на \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!'
После некоторого исследования .... оказывается, что grep -Ez [...]
это неправильный способ сделать это в работе cron.
/proc/[pid]/environ
в ОС Linux есть особенность, заключающаяся в том, что нулевой байт является разделителем записей, поэтому его содержимое при выводе на стандартный вывод «выглядит» как одна строка, то есть без символа EOL:
$ 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^@
В приведенном выше, я использовал cat
с -v
флагом, чтобы показать последовательности нулевых байтов.
Таким образом, решение состоит в том, чтобы искать шаблон "DBUS_SESSION_BUS_ADDRESS"
, распознавая нулевые байты. awk
и gawk
оба делают это, хотя это не переносимо, изменяя разделитель записей на шестнадцатеричный код для нулевого байта:\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
Это на самом деле производит чистый вывод без нулевых байтов и хорошо нравится cron
. Предупреждение не выдается и электронное письмо не отправляется.