crontab中&&连接的前序任务失败后第二个任务仍运行的原因是什么
问题原因排查
- 最常见原因:
path_to_first_bash_file.sh最终返回给调用方的退出码实际为0,和你观测到的脚本内部中间命令的退出码1不一致。比如脚本中exit 1是在子shell中执行、或者exit 1后还存在其他返回0的命令,都会导致整个脚本最终退出码为0;如果脚本内部存在将任务放到后台执行的逻辑(末尾加&),/usr/bin/sh调用脚本时会立即返回0,和后台任务最终退出码无关,也会触发&&后的第二个脚本执行。 - 退出码传递误差:你可以在crontab命令中新增左半部分退出码打印逻辑验证实际返回值,修改后测试命令如下:
0 08 * * 6 /usr/bin/sh path_to_first_bash_file.sh >> job_result-`/bin/date +\%F`.log 2>&1; echo "first script exit code: $?" >> job_result-`/bin/date +\%F`.log && /usr/bin/sh path_to_second_bash_file.sh >> job_result-`/bin/date +\%F`.log 2>&1
通过日志中打印的first script exit code确认传给&&的实际退出状态。
- shell兼容问题:crontab默认使用
/bin/sh,部分极简sh实现对退出码的传递存在异常,可以在crontab文件头部明确指定SHELL=/bin/bash规避兼容问题。 - 跨零点日志拆分:命令执行刚好跨零点时,两次
/bin/date +\%F调用会生成不同日期的日志文件,可能出现你只查看了第一个脚本的旧日期日志,第二个脚本的输出写到了新日期的日志中,误以为第二个脚本在第一个失败后执行。
修复方案
建议将执行逻辑封装到独立调度脚本中,避免crontab单行命令的隐式问题:
- 新建调度脚本
cron_job_wrapper.sh,内容如下:
#!/bin/bash log_path="job_result-$(date +%F).log" # 执行第一个脚本 /usr/bin/sh path_to_first_bash_file.sh >> "${log_path}" 2>&1 first_exit=$? if [ ${first_exit} -ne 0 ]; then echo "first script failed, exit code: ${first_exit}, skip second script" >> "${log_path}" exit ${first_exit} fi # 第一个脚本执行成功才执行第二个 /usr/bin/sh path_to_second_bash_file.sh >> "${log_path}" 2>&1
- 给脚本添加执行权限:
chmod +x /path/to/cron_job_wrapper.sh - 修改crontab定时任务为:
0 08 * * 6 /path/to/cron_job_wrapper.sh
内容的提问来源于stack exchange,提问作者jOasis
相关产品推荐
相关产品推荐

