如何获取文件的父目录?
我希望它对所有类型的名称都是安全的:
.
..
path/to/my/file
/absolute/path/to/my/file
'-rf --no-preserve-root whatever'/test.zip
(symbolic links)
`'"`'{(})
我更感兴趣的是获取文件系统上的规范位置,而不是遍历文件名中指定的路径。
请注意,与此问题存在类似问题,但没有一个问题集中在正确性,相对/绝对路径和"不安全"名称:
[1] bash get the parent directory of current directory
答案 0 :(得分:6)
真正安全的解决方案:
parent_dir="$(dirname -- "$(realpath -- "$file_name")")"
如果您的系统没有realpath
但有readlink
,那么这应该有效:
parent_dir="$(dirname -- "$(readlink -f -- "$file_name")")"
答案 1 :(得分:1)
Bash的cd
命令有几个有趣但很少使用的选项,-P
和-L
。
cd [-L|[-P [-e]] [-@]] [dir]
... The -P option causes cd to use the physical directory
structure by resolving symbolic links while traversing dir and
before processing instances of .. in dir (see also the -P option
to the set builtin command); the -L option forces symbolic links
to be followed by resolving the link after processing instances
of .. in dir. ...
所以......如果您正在寻找当前工作目录的文件系统中的物理位置,您可以使用以下内容:
realwd="$(cd -P .; pwd)"
在您的评论中,您提到您正在寻找包含文件的目录的父目录 - 因此,如果路径为/foo/bar/baz/filename
,您就是&#39 ; d正在寻找/foo/bar
。
为了得到这个,我建议cd -P
和参数扩展的组合。由于您知道/
字符永远不会作为文件名的一部分存在,因此以下内容可能对您有用:
grandparent() {
local realdir="$(cd -P "${1%/*}"; pwd)"
echo "${realdir%/*}"
}
这可以通过cd -P
使用"得到"文件的物理位置,然后参数扩展以去除路径中的最后一项。
$ mkdir -p one/two/three
$ touch one/two/three/foo
$ ln -s one/two/three bar
$ ls -l bar
lrwxr-xr-x 1 ghoti wheel 13 Nov 19 23:05 bar -> one/two/three
$ grandparent bar/foo
/usr/home/ghoti/tmp6/one/two