在Bash中从相对路径获取文件祖父目录完整路径的方法
我明白你碰到的问题了——直接嵌套dirname处理相对路径时,很容易得到.或者..这种相对结果,根本拿不到完整的绝对路径。解决这个问题的核心思路是先把任意输入路径(不管是相对还是绝对)转换成绝对路径,再提取祖父目录。下面给你两种实用的实现方法:
解决方法
方法1:依赖realpath/readlink的简洁实现
现代Linux系统基本都预装了realpath(或者GNU的readlink -f),它们能直接把相对路径转换成完整的绝对路径,完美解决dirname的痛点。你可以写一个这样的函数:
get-grand-parent() { # 先将输入路径转为绝对路径 local abs_file_path=$(realpath "$1") # 两次调用dirname:第一次取父目录,第二次取祖父目录 dirname "$(dirname "$abs_file_path")" }
如果你的系统没有realpath,可以用readlink -f替代:
get-grand-parent() { local abs_file_path=$(readlink -f "$1") dirname "$(dirname "$abs_file_path")" }
验证你的例子
当你在user@host:~/grand-parent/parent目录下执行get-grand-parent file:
realpath file会输出/home/user/grand-parent/parent/file- 第一次
dirname得到/home/user/grand-parent/parent - 第二次
dirname得到最终结果/home/user/grand-parent/,完全符合你的需求。
方法2:纯内置命令的兼容实现
如果你的环境不能用realpath或readlink,可以用Bash内置的cd和pwd命令实现,不依赖任何外部工具:
get-grand-parent() { local target="$1" # 尝试进入目标文件的祖父目录 if cd "$(dirname "$(dirname "$target")")" 2>/dev/null; then # 输出当前目录的绝对路径 pwd # 回到原来的工作目录(静默执行,不输出切换信息) cd - >/dev/null 2>&1 else # 路径无效时输出错误信息 echo "Error: 路径 $target 不存在或无效" >&2 return 1 fi }
验证你的例子
同样在~/grand-parent/parent目录下执行get-grand-parent file:
dirname file得到.,再dirname .得到..cd ..进入/home/user/grand-parent目录pwd输出完整的绝对路径/home/user/grand-parent- 最后自动回到原来的
parent目录,不影响后续操作。
注意事项
- 所有变量都用双引号包裹,避免文件名包含空格、特殊字符时出错。
- 方法2会处理路径不存在的情况,输出错误提示并返回非零状态码,方便脚本里做错误判断。
内容的提问来源于stack exchange,提问作者Justinas Marozas
相关产品推荐
相关产品推荐

