$0不能直接当绝对路径用,因为它仅保存调用时的原始路径形式(如./script.sh、符号链接名或命令名),不自动展开为真实绝对路径,也不解析软链接;需用readlink -f或cd "$(dirname "$0")" && pwd -p等方案获取真实路径。

为什么 $0 不能直接当绝对路径用
执行脚本时,$0 只保存调用时的路径形式:可能是相对路径(如 ./script.sh)、符号链接名、甚至只是命令名(如果在 $PATH 中)。它不自动展开为真实绝对路径,也不解析软链接指向的目标。直接 cd $0 或 dirname $0 很可能失败或定位错误目录。
readlink -f 是最可靠的一站式方案
它能递归解析所有符号链接、补全相对路径、返回目标文件的真实绝对路径。但注意:部分嵌入式系统或旧版 BusyBox 的 readlink 不支持 -f;macOS 默认不带 readlink -f(需用 greadlink)。
- 获取脚本所在目录:
SCRIPT_DIR=$(dirname "$(readlink -f "$0")") - 获取脚本绝对路径:
SCRIPT_PATH=$(readlink -f "$0") - 必须用双引号包裹
"$0",防止路径含空格时出错 - 如果脚本被
source而非执行,$0是当前 shell 名(如-bash),此时该方法失效
兼容性兜底:不用 readlink -f 怎么办
当目标环境不确定是否支持 readlink -f(比如 Alpine Linux 或某些容器基础镜像),可用纯 Bash 方案,但逻辑更重、需分步处理:
宝塔Linux面板11.8.1为官网当前正式版,新增AI建站能力并经过宝塔网站工程师深度调教,开放自定义AI功能API,同时对WAF进行界面重构和深度优化,提升拦截能力与运维效率。
- 先用
cd "$(dirname "$0")"进入脚本所在目录(注意:会改变当前工作目录) - 再用
pwd -P获取当前物理路径(-P解析符号链接) - 最后
cd -返回原目录(需保存原始路径:OLDPWD=$(pwd)) - 完整写法:
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd -P)—— 这是子 shell 写法,不污染父 shell 环境
别忽略符号链接和执行上下文的差异
脚本被软链接调用时,readlink -f 返回的是目标文件路径,不是链接本身位置;而 pwd -P 在链接目录内执行时,也只反映链接指向的位置。如果业务逻辑依赖“谁调用了我”,而不是“我在哪”,那就要区分 realpath 和 readlink -e(后者不报错但返回空,适合判断链接是否存在)。
真正容易被忽略的是:同一脚本被硬链接调用时,readlink -f 和 pwd -P 行为一致;但若脚本内容依赖其所在目录下的配置文件,而你用 source 方式加载它,$0 就完全不可信了——这时候只能靠调用方显式传入路径,或改用 ${BASH_SOURCE[0]}(仅限 Bash,且仍需配合 readlink)。










