crontab默认使用/bin/sh执行脚本;centos 7中该shell指向bash的posix兼容模式,不支持[[ ]]、source、数组等bash特有语法,且path极窄、不加载用户配置文件,导致手动正常而定时失败。

crontab 默认用什么 Shell 执行脚本
CentOS 7 的 crond 守护进程默认使用 /bin/sh(不是 /bin/bash)来执行 crontab 中定义的任务,无论你当前用户登录用的是 bash 还是 zsh。这个行为由 crond 源码硬编码决定,无法通过用户环境变量(如 $SHELL)覆盖。
为什么脚本在 crontab 里执行失败,但手动运行正常
常见现象:脚本含 [[ ]] 、source ~/.bashrc、数组、$(date -d ...) 等 bash 特有语法,手动执行没问题,放进 crontab 就报错或静默失败 —— 基本就是被 /bin/sh 解释器拒绝了。
-
/bin/sh在 CentOS 7 上通常指向bash的 POSIX 兼容模式,不支持[[、let、declare、source(只认.)、大括号扩展等 - 环境变量缺失:
PATH极简(通常是/usr/bin:/bin),HOME可能不对,~展开失效 - 没有加载用户 profile 或 rc 文件,所以自定义 alias、函数、PATH 补充全都不生效
强制 cron 用 bash 执行单个脚本的 3 种可靠方式
不改系统级默认 shell(没必要也不推荐),而是让任务「自己指定解释器」:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 在脚本第一行明确写
#!/bin/bash,且确保脚本有执行权限(chmod +x /path/to/script.sh),然后在 crontab 里直接调用该脚本路径 —— 这是最常用、最安全的做法 - 在 crontab 条目中显式调用 bash:
0 2 * * * /bin/bash /home/user/backup.sh >> /var/log/backup.log 2>&1 - 在脚本开头加
set -e -u和完整路径调用命令(如/usr/bin/date),避免依赖 PATH;用.替代source;用[ ]替代[[ ]]—— 适配/bin/sh,但牺牲可读性和功能
不要碰 /etc/crontab 的 SHELL= 行
虽然 /etc/crontab 文件顶部有 SHELL=/bin/bash 这样的注释行,但它**仅对 /etc/crontab 文件里定义的系统级任务生效**,且必须是 root 用户编辑该文件才起作用。普通用户用 crontab -e 编辑的条目完全无视这一行 —— 这是 crond 的设计限制,不是 bug。
强行修改它还可能被系统更新覆盖,或导致其他服务(如 logrotate)调用异常。真正要改,也只应在 /etc/crontab 里为特定 root 任务加 /bin/bash -c '...' 包裹,而不是全局改解释器。
关键点就一个:cron 不管你登录用啥 shell,它只认自己的规则;想用 bash,就在脚本头写死 #!/bin/bash 或 crontab 里显式调用 /bin/bash,别指望环境变量或全局配置替你兜底。










