根本原因是cron默认工作目录为用户家目录且不展开~,导致脚本中./、../、~等相对路径失效;应加cd "$(dirname "$0")"切换目录、全用绝对路径、添加路径存在性校验并用env -i模拟cron环境验证。

备份脚本在终端能跑通,放进 crontab 却没反应、没文件、没报错——这大概率是路径错误引发的静默失败。根本原因在于 cron 启动时工作目录默认是用户家目录(如 /home/user),而脚本里写的 ./config.ini、../data 或 ~/backup 全部失效。
确认当前工作目录是否被误用
脚本中所有相对路径(./、../、~)都依赖执行时的当前目录。cron 不会自动 cd 到脚本所在位置,也不会展开 ~。
- 在脚本开头加一行:
echo "PWD: $(pwd)" >> /var/log/backup/debug.log,运行后查看日志里实际的工作目录 - 检查脚本是否用了
~:cron 环境不识别该符号,必须写成完整路径,例如/home/user/backup - 避免
cd ..类操作,除非你明确知道起始位置;更稳妥的是用cd "$(dirname "$0")"切到脚本自身所在目录
验证路径是否存在且可访问
路径写对了,不代表就能用。权限、挂载状态、拼写大小写都可能让 ls /mnt/backup 返回空或报错,而脚本若没做判断就继续执行,后续命令可能静默跳过。
- 在脚本关键路径前加检测:
if [[ ! -d "/mnt/backup" ]]; then echo "ERROR: backup dir missing" >&2; exit 1; fi - 用
ls -ld /mnt/backup查看目录权限和属主,确认执行备份的用户有读写权 - 若路径在 NFS 或 CIFS 挂载点上,运行
mount | grep /mnt/backup确认已成功挂载,未出现stale file handle
检查脚本内所有路径是否为绝对路径
相对路径是静默失败高发区。即使你写了 cd "$(dirname "$0")",后续命令仍可能因环境变量缺失或子 shell 隔离而失效。
- 把配置文件、日志、输出目标等全部改用绝对路径,例如:
/opt/backup/conf/settings.conf、/var/log/backup/mysql_backup.log - 数据库导出目标不要写
backup.sql,而应写/mnt/backup/mysql_$(date +\%Y\%m\%d).sql - 临时文件路径也要显式指定,避免写入
/tmp后被其他进程清理或权限拦截
用 cron 环境模拟真实执行过程
别只信手动执行结果。真正的问题只在 cron 的极简环境中暴露。
- 用以下命令模拟 cron 执行:
sudo -u youruser env -i PATH=/usr/bin:/bin /bin/bash -c '/path/to/backup.sh' - 如果报
No such file or directory,重点查 shebang 行是否指向有效解释器(如#!/bin/bash)、脚本本身是否有执行权限(chmod +x) - 若提示
command not found,说明路径没错但命令找不到——这时要查 PATH,不是脚本路径


















