在 Arch 上设置 `cron` 作业并在发生错误时发送邮件

在 Arch 上设置 `cron` 作业并在发生错误时发送邮件

我使用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。不会产生任何警告,也不会发送电子邮件。

相关内容