我使用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 发送电子邮件发送特定警告,我的玩具示例将正常运行。我该如何摆脱它?
答案1
\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!'
答案2
经过一番研究......事实证明,这grep -Ez [...]
不是在 cron 作业中执行此操作的正确方法。
/proc/[pid]/environ
在 Linux 操作系统中,空字节是记录分隔符,因此其内容在输出到 stdout 时“看起来”像一行,即没有 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 {RS="\x00"} /DBUS_SESSION_BUS_ADDRESS/' /proc/$(pgrep -u $LOGNAME gnome-session)/environ
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
这实际上会产生一个干净的输出,没有空字节,并且很受人们的欢迎cron
。不会产生任何警告,也不会发送电子邮件。