bash 在bash中获取文件的父目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40700119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:26:08  来源:igfitidea点击:

get parent directory of a file in bash

linuxbashshellsh

提问by VasiliNovikov

How do I get a parent directory for a file?

如何获取文件的父目录?

I want it to be safe on all kind of names:

我希望它对所有类型的名称都是安全的:

.
..
path/to/my/file
/absolute/path/to/my/file
'-rf --no-preserve-root whatever'/test.zip
(symbolic links)
`'"`'{(})

I am more interested getting the canonical location on the file system than in traversing the path stated in the filename.

我对获取文件系统上的规范位置比遍历文件名中指定的路径更感兴趣。

Note that there are similar questions to this one, but none of them focuses on correctness, relative/absolute paths and "unsafe" names:

请注意,有与此类似的问题,但没有一个关注正确性、相对/绝对路径和“不安全”名称:

[1] bash get the parent directory of current directory

[1] bash 获取当前目录的父目录

[2] Retrieve parent directory of script

[2]检索脚本的父目录

[3] bash filepath to parent directory of file

[3] bash 文件路径到文件的父目录

回答by VasiliNovikov

Really safe solution:

真正安全的解决方案:

parent_dir="$(dirname -- "$(realpath -- "$file_name")")"

If your system does not have realpathbut does have readlink, this should work:

如果您的系统没有realpath但确实有readlink,这应该有效:

parent_dir="$(dirname -- "$(readlink -f -- "$file_name")")"

回答by ghoti

Bash's cdcommand has a couple of interesting but little-used options, -Pand -L.

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. ...

So ... if you're looking for the physical location in the filesystem of your current working directory, you could use something like this:

所以......如果你正在当前工作目录的文件系统中寻找物理位置,你可以使用这样的东西:

realwd="$(cd -P .; pwd)"

In your comments, you mentioned that you're looking for the parent directory of the directorycontaining a file -- so, if a path is /foo/bar/baz/filename, you'd be looking for /foo/bar.

在您的评论中,您提到您正在查找包含文件的目录的父目录- 因此,如果路径是/foo/bar/baz/filename,您将查找/foo/bar.

To get this, I would suggest a combination of cd -Pand parameter expansion. Since you know that the /character can never exist as part of a filename, the following might work for you:

为此,我建议结合cd -P和 参数扩展。由于您知道该/字符永远不会作为文件名的一部分存在,因此以下内容可能对您有用:

grandparent() {
    local realdir="$(cd -P "${1%/*}"; pwd)"
    echo "${realdir%/*}"
}

This works by using cd -Pto "get" the physical location of the file, then parameter expansion to strip off the last item in the path.

这通过使用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