dirname返回路径字符串而非切换目录,如dirname /home/user/script.sh输出/home/user,但不改变当前工作目录;常用于脚本中获取上级路径,需配合cd或变量赋值使用。

dirname 返回的是路径字符串,不是自动切换目录
很多人以为 dirname 会像 cd 那样改变当前工作目录,其实它只是计算并输出上级路径字符串。比如 dirname /home/user/script.sh 输出的是 /home/user,但 shell 当前目录完全不变。
常见错误现象:写完 dirname $0 就直接用 ls *.conf,结果报错“找不到文件”——因为脚本可能在别处执行,当前目录不是脚本所在目录。
- 正确做法是显式进入该目录:
cd "$(dirname "$0")"(注意双引号和命令替换) - 如果只是需要路径做拼接,直接赋值给变量:
SCRIPT_DIR="$(dirname "$0")" - 避免裸用
dirname $0:未加引号时,路径含空格会截断;未用命令替换时,只是字面打印不参与后续逻辑
dirname 处理相对路径时行为易被忽略
dirname 对相对路径的解析严格按字符串规则,不依赖真实文件系统。比如 dirname a/b/c 总是返回 a/b,哪怕 a 根本不存在;dirname ./file.txt 返回 .,而不是当前绝对路径。
使用场景:写可移植脚本时,若想获取脚本的**绝对路径所在目录**,不能只靠 dirname "$0"。
- 先转成绝对路径:
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" - 或用
readlink -f(GNU 系统):SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" - 注意
readlink -f在 macOS 或最小化 Linux(如 Alpine)上可能不可用,需 fallback 到pwd方案
dirname 在管道或循环中容易误用空值
当输入为空、仅含文件名(无斜杠)、或为 / 时,dirname 行为特殊:dirname abc 返回 .,dirname / 返回 /。这在批量处理文件列表时容易导致意外的 . 或根目录。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
常见错误现象:用 find . -name "*.sh" -exec dirname {} \; 批量提取目录,结果混入大量 .,后续 cd 失败。
- 过滤掉纯文件名输入:
[[ "$file" == */* ]] && dirname "$file" - 统一转绝对路径再处理,避免
.干扰:dirname "$(realpath "$file")" - 注意
realpath同样非 POSIX,BusyBox 环境下需改用cd "$(dirname "$file")"; pwd; cd -组合
bash 里 dirname 不是内置命令,调用有开销
dirname 是外部命令(通常位于 /usr/bin/dirname),每次调用都会 fork 子进程。高频循环中反复调用会影响性能,尤其在嵌入式或容器轻量环境。
性能影响:万次调用比纯 shell 参数扩展慢 10–50 倍(实测取决于系统负载)。
- 优先用 bash 参数扩展替代简单场景:
${file%/*}等价于dirname "$file",但更快更轻量 - 注意区别:
${file%/*}对abc返回空串,而dirname abc返回.;需按需补全:[[ -z "${file%/*}" ]] && dir="." || dir="${file%/*}" - 复杂路径(如
../../a/b)仍建议用dirname,参数扩展无法处理..语义
实际脚本里最常出问题的,是没区分“路径计算”和“目录切换”,以及默认假设 $0 的路径总是绝对或可直接用。多一层 cd "$(dirname "$0")" 或 realpath 包裹,能避开 80% 的路径相关故障。

















