从函数内部执行邮件命令会导致“叉子炸弹”


8

当我尝试mail从bash脚本中的函数内部执行时,它会创建类似于fork炸弹的内容。为了澄清,这会引起问题:

#!/bin/bash

mail() {
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "example@example.org"
}

mail

exit 0

有时您只需要杀死该命令,它就会杀死子进程,但是有时您必须这样做killall -9

不管邮件是否已发送。该叉炸弹创建两种方式。而且似乎没有为退出代码添加任何检查,例如if ! [ "$?" = 0 ]帮助。

但是以下脚本可以按预期工作,要么输出错误,要么发送邮件。

#!/bin/bash

echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "example@example.org"

exit 0

为什么会这样?以及如何检查mail命令的退出代码?


10
这称为递归。
雅库耶

Answers:


29

你调用该函数 mail从同一个函数中:

#!/bin/bash

mail() {
    # This actually calls the "mail" function
    # and not the "mail" executable
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "example@example.org"
}


mail

exit 0

这应该工作:

#!/bin/bash

mailfunc() {
    echo "Free of oxens" | mail -s "Do you want to play chicken with the void?" "example@example.org"
}

mailfunc

exit 0

请注意,不再从函数本身内部调用函数名称。


3
属于我们最好的,伙计。
Almo

15

除此以外:

mail(){

    echo olly olly oxenfree | command mail -s 'and the rest' and@more
}

...应该工作正常。


7
也许是强调该command部分,对于外行来说,很难注意到随着olly olly oxenfree和的'and the rest' and@more变化,尤其是语法高亮显示的变化。
wizzwizz4 2016年

1
@ wizzwizz4-我支持此评论。
mikeserv

1
不过,这有趣……
wizzwizz4 '16

3

在这些情况下,最“传统”的解决方案实际上是使用完整路径调用命令:

mail() {
    echo "Free of oxens" | /usr/bin/mail -s "Do you want to play chicken with the void?" "example@example.org"
}

所有其他答案都可行,并且可能更易于移植,但是我认为这是您在狂野的现实世界中的脚本中找到的最可能的解决方案,因此为了完整起见,我将其包括在内。


3
确实,我不习惯将邮件放在/ usr / bin中。
约书亚

3
@Joshua,它似乎存在于OS X上。在CentOS 6中是/bin/mail。我认为这证明了command mail语法的价值。
通配符

Arch Linux也有此功能,/usr因为它们的范例是将所有二进制文件都移到同一目录,因此/bin只是一个符号链接/usr/bin。所以是的...这不是可移植的,但是比command某种程度上更常见-特别是在为每个发行版专门制作的旧版启动脚本中,所有绝对路径都是硬编码的(例如,Slackware中的rc脚本)。
Orion
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.