必须在crontab文件最开头(无空行、无注释)声明shell=/bin/bash,且需同步配置path和home变量,否则命令找不到或路径展开失败;脚本头部应写#!/bin/bash并用绝对路径调用。

直接在 crontab 文件顶部写 SHELL=/bin/bash 就能强制所有任务使用 Bash 解释器执行,但仅写这一行还不够——它只是“声明”,真正起效需要配合正确的语法位置、环境一致性以及避免常见陷阱。
必须放在 crontab 文件最开头(且不能有空行)
crontab 读取时会逐行解析,环境变量声明必须出现在任何定时任务条目之前,且前面不能有空行或注释。一旦中间插入空行,后续的 SHELL 设置就失效了。
- ✅ 正确写法(第一行即声明):
SHELL=/bin/bash<br>PATH=/usr/local/bin:/usr/bin:/bin<br>0 2 * * * /home/user/backup.sh
- ❌ 错误写法(空行隔开或位置靠后):
# 备份任务<br><br>SHELL=/bin/bash<br>0 2 * * * /home/user/backup.sh
→ 这里的 SHELL 不生效
为什么只设 SHELL 不够?还得配 PATH 和 HOME
Bash 环境不等于“你终端里能跑的环境”。cron 默认 PATH 极其精简(通常只有 /bin:/usr/bin),HOME 也可能是 / 或未定义,导致脚本里用的命令(如 python3、jq、mysqldump)找不到,或者 ~ 展开失败、配置文件(如 ~/.bashrc)不加载。
- 务必同步声明:
SHELL=/bin/bash<br>PATH=/usr/local/bin:/usr/bin:/bin:/home/username/.local/bin<br>HOME=/home/username
-
HOME设对了,脚本里用~/scripts/才能正确展开;PATH包含常用路径,才能直接调python3而不用写/usr/bin/python3
验证是否真用了 Bash,而不是 sh
有些系统默认 /bin/sh 是 dash(Ubuntu)或其它轻量 shell,不支持数组、[[、source 等 Bash 特性。光靠 SHELL 声明不能 100% 保证——还要看脚本第一行和实际调用方式。
- 脚本头部明确写
#!/bin/bash(推荐) - crontab 中调用时别省略解释器:写成
/bin/bash /path/to/script.sh比直接/path/to/script.sh更可靠 - 简单测试:加一行
* * * * * echo $0 > /tmp/shell_test.log,运行后查看日志内容是不是/bin/bash
注意系统级 crontab(/etc/crontab)和用户级的区别
用户用 crontab -e 编辑的是自己的 crontab 文件,顶部声明 SHELL 等变量完全有效;但如果是直接编辑 /etc/crontab 或 /etc/cron.d/xxx,格式不同——它们每行多一个「执行用户」字段,且环境变量声明同样有效,但必须写在任务条目前面。
-
/etc/crontab示例:SHELL=/bin/bash<br>PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin<br>MAILTO=root<br>0 3 * * * root /usr/local/bin/daily-maint.sh
- 这里
root是执行用户,SHELL 和 PATH 对这行任务生效











