crontab中mysqldump命令找不到是因默认path窄(仅/usr/bin:/bin),需显式设置path或用绝对路径;密码含特殊字符须单引号包裹或使用--defaults-extra-file;务必重定向stderr并用绝对路径、显式cd,模拟crontab环境测试。

crontab里找不到mysqldump命令?先查PATH和which
crontab默认的PATH非常窄(通常是/usr/bin:/bin),不包含MySQL安装路径,所以即使which mysqldump在终端返回/usr/local/mysql/bin/mysqldump,crontab里直接写mysqldump也会报command not found。
实操建议:
- 在脚本开头显式设置PATH:
export PATH="/usr/local/mysql/bin:/usr/bin:/bin" - 或直接用绝对路径调用:
/usr/local/mysql/bin/mysqldump -u user -p'pass' db_name > backup.sql - 别信
echo $PATH在shell里输出的结果——那是你当前shell的PATH,不是crontab的 - 加一句
env > /tmp/cron_env.log到crontab任务里,跑一次就能看到它实际用的环境变量
密码含特殊字符导致crontab执行失败
crontab解析命令时,shell语法比交互式终端更严格。像-p@123!#这种密码,!会被bash当作历史扩展符,#会被当注释起始,结果传给mysqldump的密码就错了,报Access denied但没提示哪错了。
实操建议:
- 密码统一用单引号包裹:
-p'@123!#'(注意:不能用双引号,变量会扩展) - 更稳妥的做法是用
--defaults-extra-file,把账号密码写进独立文件(如/etc/mysql/backup.cnf),并设权限chmod 600 - 文件内容格式必须严格:
[client] user=backup_user password=@123!#
,开头不能有空格或BOM,结尾不能有多余空行
crontab日志为空或只显示“exited with code 1”
crontab默认不捕获stderr,错误信息直接丢弃。你看到“command exited with code 1”,却不知道是权限错、路径错还是连接超时。
实操建议:
- 所有crontab任务末尾必须重定向stderr:
2>&1 >> /var/log/backup.log - 避免用
>覆盖日志——多个备份任务会互相擦除;用>>追加 - 在脚本里检查
$?并记录:if [ $? -ne 0 ]; then echo "$(date) mysqldump failed" >> /var/log/backup.log; exit 1; fi - 别依赖
set -e——crontab里某些shell不完全支持,显式判断更可靠
脚本在shell能跑,crontab里失败:HOME和工作目录差异
crontab以系统用户身份运行,HOME是/root或/var/spool/cron,不是你的/home/user。脚本里写的相对路径(如./backup.sql、config.ini)会找错地方;ssh密钥、my.cnf默认读取位置也会失效。
实操建议:
- 脚本开头强制切换工作目录:
cd /opt/backup || exit 1 - 所有路径用绝对路径:
/opt/backup/backup_$(date +\%F).sql,别用backup_$(date +%F).sql - 如果依赖
~/.my.cnf,显式指定:mysqldump --defaults-file=/root/.my.cnf ... - 测试时用
sudo -u root bash -c 'env -i HOME=/root PATH=/usr/bin:/bin /opt/backup/backup.sh'模拟crontab环境











