cd "$(dirname "$0")"可将脚本工作目录切换至其所在目录,解决cron等场景下因默认home路径导致的相对路径文件查找失败问题,且需加双引号防空格错误。

直接在脚本开头加 cd "$(dirname "$0")",就能解决绝大多数因相对路径引发的“找不到文件”问题。
确认脚本执行时的实际工作目录
crontab 默认以用户 HOME 目录为工作路径,不是脚本所在目录。哪怕你写的是 /home/user/bin/run.sh,里面用 ./config.json 或 ../data/input.txt,也会去 /home/user/ 下找——而不是 /home/user/bin/。
验证方法:在脚本第一行插入:
echo "PWD: $(pwd)" > /tmp/cron_debug.log- 或更完整:
env | grep -E "^(PWD|HOME|PATH)$" >> /tmp/cron_debug.log
等任务触发后查看 /tmp/cron_debug.log,就能清楚看到 cron 实际在哪运行、环境变量是什么。
统一切换到脚本自身目录
这是最简单、最可靠的修复方式。在脚本最开头(#!/bin/bash 之后立即)加上:
cd "$(dirname "$0")" || exit 1- 这行会把当前工作目录切到脚本所在的绝对路径,后续所有
./xxx、../conf/都能按预期定位 - 注意:必须用
"$(dirname "$0")",不能写成$(dirname $0)(未引号包裹遇空格会出错)
检查脚本内所有路径调用是否安全
光改工作目录还不够——如果脚本里调用了其他脚本、读取配置、写日志,仍可能出问题:
-
python3 main.py→ 改成python3 "$(dirname "$0")/main.py"或直接用绝对路径 -
cat config.yaml→ 改成cat "$(dirname "$0")/config.yaml" -
echo "done" > output.log→ 改成echo "done" > "$(dirname "$0")/output.log"或指定日志绝对路径
尤其注意 Python 的 open("data.csv")、Java 的 new File("conf/") 这类代码,它们都依赖当前工作目录。
配合日志重定向快速定位报错
不看输出,等于没排查。在 crontab 条目末尾强制捕获全部输出:
0 3 * * * /home/user/app/run.sh >> /home/user/app/run.log 2>&1- 确保日志路径存在且可写:
mkdir -p /home/user/app && chmod 755 /home/user/app - 典型报错如
No such file or directory、Permission denied都会出现在日志里,结合前面的pwd输出,一眼就能看出是路径错了还是权限不够











