Shell脚本手动执行正常但经cron调度运行失效的问题排查咨询
Cron调度Shell脚本失效排查
结合你当前排查进度的高概率失效原因
你已经完成了初步排查:其他Cron调度的脚本运行正常、手动执行当前脚本功能正常、终端与Cron场景环境变量基本一致、异常脚本与正常脚本唯一差异是存放路径。结合这个前提,故障基本集中在以下三个场景:
- 相对路径依赖工作目录偏移:脚本核心逻辑
find . -name "*.log" -delete使用了相对路径,执行时会以当前工作目录为根递归扫描。手动执行时,你所在的终端当前路径就是预期要清理日志的目标目录;但Cron启动任务时,默认会将当前工作目录设置为执行Cron任务的用户家目录(比如root用户跑的话默认就是/root),完全不会自动切换到脚本存放的目录。这也刚好解释了你感知到的“两个脚本仅存放路径不同结果不一样”的差异——其他正常运行的脚本没有使用依赖当前工作目录的相对路径命令,因此不受这个偏移影响。
排查方式很简单:在脚本最开头加一行pwd >> /tmp/cron_debug.log,手动触发一次Cron任务,看日志里输出的路径是不是你预期要扫描日志的目录,大概率和你想的完全不一样。修复可以二选一:- 把
find .替换为目标扫描目录的绝对路径,比如find /data/app/logs -name "*.log" -delete - 在脚本开头加一行自动切目录的命令:
cd "$(dirname "$0")",让脚本启动后先切到自身所在的目录,完全匹配手动执行时的工作目录状态
- 把
- Cron无交互环境下的sudo授权失效:脚本里加了
sudo,但Cron运行时没有任何交互输入通道,根本无法响应sudo弹出的密码输入提示。如果Cron执行的用户没有在sudoers配置里绑定find命令的免密执行权限,sudo会直接因权限校验失败中断运行。考虑到你提到Cron运行的用户本身权限级别更高,这个问题概率稍低,但也需要排除——比如你用root用户跑Cron的话,根本不需要加sudo,直接去掉就行。 - 脚本存放分区的执行权限限制:如果当前异常脚本存放在挂载时带
noexec参数的分区(很多系统默认给/tmp这类临时目录加noexec参数,禁止分区内的程序直接执行),哪怕脚本内容和正常脚本100%一致,Cron也没法直接运行这个脚本。其他正常脚本都是放在带exec执行权限的分区里,因此运行正常,这也完全匹配你提到的“两个脚本仅存放路径不同”的差异特征。
精准定位问题的日志获取方法
不用反复导出环境变量对比找差异,直接把脚本改造为全量输出日志的版本,所有运行问题都会直接暴露:
可直接复用的调试脚本结构:
#!/bin/sh { echo "===== 任务启动时间: $(date) =====" echo "当前执行路径: $(pwd)" echo "当前执行用户: $(whoami)" find . -name "*.log" -delete echo "find命令执行退出码: $?" } >> /tmp/script_debug.log 2>&1触发一次Cron调度后,直接查看
/tmp/script_debug.log的内容,所有路径偏移、权限报错、命令执行失败的原因都会被完整记录,不需要靠模糊猜测定位问题。
内容的提问来源于stack exchange,提问作者Castiell
相关产品推荐
相关产品推荐

