如果从中输出,我如何才能将此命令重写为仅电子邮件mailq | grep
?
mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -s 'dd' email@email
甚至可以单行吗?
请参阅检查管道是否为空,如果不是比发送电子邮件更一般的情况,请对数据运行命令。
如果从中输出,我如何才能将此命令重写为仅电子邮件mailq | grep
?
mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -s 'dd' email@email
甚至可以单行吗?
请参阅检查管道是否为空,如果不是比发送电子邮件更一般的情况,请对数据运行命令。
Answers:
我认为您将必须使用一个临时文件来执行此操作,以便&&
仅当grep返回退出状态(表明其具有以下匹配项)时,才可以使用运算符来运行mail命令:
TMPFILE=`mktemp /tmp/mailqgrep.XXXXXX`; mailq | egrep 'rejected|refused' -A5 -B5 > "$TMPFILE" && mail -s 'dd' email@email < "$TMPFILE"; rm "$TMPFILE"
如果您不介意临时文件停留在某个地方并且可以使用静态名称,则可以跳过特殊的命名和删除内容:
mailq | egrep 'rejected|refused' -A5 -B5 > /tmp/mailqgrep && mail -s 'dd' email@email < /tmp/mailqgrep
编辑:看到格伦的答案后,我对此进行了更多$()
的尝试,显然使用语法分配了变量将返回命令的退出代码,因此您可以跳过他用于字符串长度的测试,而改用它。这是一个命令中的全部内容:
data=$(mailq | egrep 'rejected|refused' -A 5 -B 5) && mail -s 'dd' email@email <<< "$data"
编辑2:看到西蒙的答案后,我签出了我的mail
程序。默认情况下,它的行为方式与他描述的方式不同,但是有一个选项。从手册页:
-E
如果外发消息的第一个或唯一消息部分不包含任何文本,请不要发送该消息,而应将其静默丢弃,从而在程序启动时有效地设置了skipemptybody变量。这对于从cron(8)启动的脚本发送消息很有用。
使之成为可能:
mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -E -s 'dd' email@email
mktemp
不会返回需要引用的内容,因此该编辑是不必要的。
glob(split(var))
。您无需在此处进行字分割或文件扩展,所以不需要它们。另外,我们需要在此网站上显示正确的方法。
zsh
,除非出现此类情况,否则在这种情况下实际上不会出现混乱或单词分裂的情况,但出于此处的答案,并且不知道目标环境引用不正确,这是可以的。
您可以将输出保存在变量中,然后在字符串的长度不为零的情况下调用mail命令。
data=$(mailq | egrep 'rejected|refused' -A 5 -B 5)
[[ -n "$data" ]] && mail -s 'dd' email@email <<< "$data"
对于一行,将两个命令用分号连接起来。
mail
与该-E
选项一起使用。在我的Mac上,MAIL(1)说该-E
标志不会发送带有空正文的电子邮件。
-E不要发送带有空正文的消息。这对于cron(8)脚本中的管道错误很有用。
在Mac上,我运行了以下测试。请注意该文件file_does_exist
确实存在,但该文件file_does__not_exist
不存在。
这会向我发送电子邮件:
$ ls file_does_exist | egrep 'file' -A5 -B5 | mailx -E -s 'test' stefan@example.org
这不是。请注意,该命令ls file_does_not_exist | egrep ...
不会产生任何输出。
$ ls file_does_not_exist | egrep 'file' -A5 -B5 | mailx -E -s 'test' stefan@example.org
ls: file_does_not_exist: No such file or directory
在这种情况下,如果您mail
支持该-E
选项,则只需使用它即可。在一般情况下,您可以尝试读取一个字符。如果存在,则启动后处理命令,并从文件的其余部分中输入该字符。
pipe_if_not_empty () {
a=$(dd bs=1 count=1 2>/dev/null; echo .) # read at most one character
if [ "$a" != "." ]; then # if there were two characters,
{ printf %s "${a%.}"; # then output the first character
cat; } | # and the rest of the input
"$@" # into the specified program
fi
}
mailq | egrep 'rejected|refused' -A 5 -B 5 |
pipe_if_not_empty mail -s 'dd' email@email
请注意的有用用法cat
。加入的echo .
品牌即使在输入第一个字符是换行该功能的工作(记住,$(…)
构建去掉终端新行)。
对于大多数shell(据我所知,除zsh以外的任何东西),如果文件以空字符开头,则此代码将认为它为空。剩下的解决方法是作为练习供读者阅读。(提示:od
在第一个子shell中使用并printf
打印第一个字节。)(解决方案:如何检查管道是否为空)如果文件开头的字节不是当前的有效字符,则可能会遇到相同的问题语言环境 使用来运行此代码更容易解决LC_ALL=C
。
read
帮助可以简化此过程吗?
read
在可移植的sh中将空的第一行与空文件区分开(在bash,ksh或zsh中可能如此)。