mat*_*mat 2 linux shell bash cron debian
在 Debian 8.1 上,我使用Bash功能来检测是否可以访问 stackoverflow.com 网站:
(echo >/dev/tcp/stackoverflow.com/80 ) &>/dev/null || 回声“无法访问stackoverflow”
这是 Bash 特定的sh,在cron.
如果我们故意尝试 中的脚本sh,我们会得到:
$ /bin/sh: 1: cannot create /dev/tcp/stackoverflow.com/80: Directory nonexistent
因此,如果我只将以下内容放在我的个人 crontab 中(没有设置SHELL为/bin/bash) via crontab -e,我希望每分钟执行一次脚本,因此我希望每分钟每封邮件发送一次上述错误:
* * * * * (echo >/dev/tcp/stackoverflow.com/80) &>/dev/null || 回声“无法访问stackoverflow”
事实上,正如预期的那样,我们从/var/log/syslog条目中看到每分钟执行一次:
# sudo grep stackoverflow /var/log/syslog Aug 24 18:58:01 localhost CRON[13719]: (mat) CMD ((echo >/dev/tcp/stackoverflow.com/80) &>/dev/null ||回声“无法访问stackoverflow”) 8 月 24 日18:59:01本地主机 CRON[13723]: (mat) CMD ((echo >/dev/tcp/stackoverflow.com/80) &>/dev/null || echo "stackoverflow unreachable") 8 月 24 日19:00:01本地主机 CRON[13727]:(mat) CMD ((echo >/dev/tcp/stackoverflow.com/80) &>/dev/null || echo "stackoverflow unreachable") ...
在过去的大约 2 个小时内,这已经执行了 120 多次,因为我可以通过将输出管道传输到wc -l.
但是,从这些 >120 次的 shell 命令(重复:shell 命令对 无效/bin/sh)执行后,我只收到了三封电子邮件:
第一个在 19:10:01,第二个在 20:15:01,第三个在 20:57:01。
所有三封邮件的内容都完全符合预期,并且包含在不兼容的 shell 中(故意)运行脚本所预期的错误消息。例如,我收到的第二封邮件显示(另外两封几乎完全相同):
来自 mat@myhost.com 2015 年 8 月 24 日星期一 20:15:01 来自:root@myhost.com(Cron Daemon) 至:mat@myhost.com 主题:Cron (echo >/dev/tcp/stackoverflow.com/80)&>/dev/null || 回声“无法访问stackoverflow” ... /bin/sh: 1: 无法创建 /dev/tcp/stackoverflow.com/80: 目录不存在`
从/var/log/mail.log,我看到这三封邮件是过去几个小时内发送和接收的唯一邮件。
因此,由于错误脚本创建的上述输出,我们希望从 cron 收到的 >100 封额外邮件在哪里?
总结一下:
/usr/bin/sendmail。有很多方法可以解决导致上述观察结果的明显错误:
SHELL=/bin/bash在我的crontab.heartbeat.shwith #!/bin/bash,然后调用它。/bin/bash -c ...中crontab。sh.然而,所有这些都没有解决这个问题的核心问题,即在这种情况下,cron即使脚本总是创建输出,也不能可靠地发送邮件。
我已经验证脚本总是通过创建来创建输出wrong.sh(它再次故意使用不合适的/bin/sh外壳,以产生cron应该看到的相同错误):
#!/bin/sh (echo >/dev/tcp/stackoverflow.com/80) &>/dev/null || 回声“无法访问stackoverflow”
现在我可以在循环中调用脚本,看看是否存在它在不创建输出的情况下完成的情况。使用Bash:
$ 为真;做 [[ -n $(./wrong.sh 2>&1 ) ]]; 回声 $?; 完成 | grep -v 0
即使在数千次调用中,我也无法重现脚本完成而不创建输出的情况。
这种不可预测的行为可能是什么原因?任何人都可以重现这个吗?对我来说,看起来可能存在竞争条件,cron 可能会错过脚本的输出,可能主要涉及错误源于 shell 本身的情况。谢谢!
经过进一步测试,我怀疑这&会影响您的结果。正如您所指出的,&>/dev/null是bash语法,而不是sh语法。因此,sh正在创建一个子外壳并将其作为背景。当然,子外壳echo会创建 stderr,但我的理论是:
|| echo .......导致 cron 作业没有输出,因此没有邮件。根据我对 vixie-cron 源代码的阅读,似乎作业的 stderr 和 stdout 会被 cron 捕获,但它肯定会被 subshell 丢失。
在 /bin/sh 环境中自行测试(假设您这里没有名为“bar”的文件):
(grep foo bar) &
echo $?
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1934 次 |
| 最近记录: |