是否有一个命令来检索给定相对路径的绝对路径?

例如,我想要$line包含dir ./etc/中每个文件的绝对路径

find ./ -type f | while read line; do
   echo $line
done

当前回答

我发现Eugen Konkov的答案是最好的,因为它不需要安装任何程序。但是,对于不存在的目录,它将失败。

我写了一个函数,适用于不存在的目录:

function getRealPath()
{
    local -i traversals=0
    currentDir="$1"
    basename=''
    while :; do
        [[ "$currentDir" == '.' ]] && { echo "$1"; return 1; }
        [[ $traversals -eq 0 ]] && pwd=$(cd "$currentDir" 2>&1 && pwd) && { echo "$pwd/$basename"; return 0; }
        currentBasename="$(basename "$currentDir")"
        currentDir="$(dirname "$currentDir")"
        [[ "$currentBasename" == '..' ]] && (( ++traversals )) || { [[ traversals -gt 0 ]] && (( traversals-- )) || basename="$currentBasename/$basename"; }
    done
}

它通过使用dirname向上遍历直到cd成功,然后返回当前目录加上dirname删除的所有内容来解决不存在目录的问题。

其他回答

我发现Eugen Konkov的答案是最好的,因为它不需要安装任何程序。但是,对于不存在的目录,它将失败。

我写了一个函数,适用于不存在的目录:

function getRealPath()
{
    local -i traversals=0
    currentDir="$1"
    basename=''
    while :; do
        [[ "$currentDir" == '.' ]] && { echo "$1"; return 1; }
        [[ $traversals -eq 0 ]] && pwd=$(cd "$currentDir" 2>&1 && pwd) && { echo "$pwd/$basename"; return 0; }
        currentBasename="$(basename "$currentDir")"
        currentDir="$(dirname "$currentDir")"
        [[ "$currentBasename" == '..' ]] && (( ++traversals )) || { [[ traversals -gt 0 ]] && (( traversals-- )) || basename="$currentBasename/$basename"; }
    done
}

它通过使用dirname向上遍历直到cd成功,然后返回当前目录加上dirname删除的所有内容来解决不存在目录的问题。

Realpath可能是最好的

但是…

最初的问题一开始就很混乱,没有一个很好的例子 与刚才提到的问题有关。

所选的答案实际上回答了给出的例子,但根本不是 题目中的问题。第一个命令是答案(is it 真的吗?我怀疑),没有'/'也可以。我看不见 第二个命令在做什么。

有几个问题是复杂的:

changing a relative pathname into an absolute one, whatever it denotes, possibly nothing. (Typically, if you issue a command such as touch foo/bar, the pathname foo/bar must exist for you, and possibly be used in computation, before the file is actually created.) there may be several absolute pathname that denote the same file (or potential file), notably because of symbolic links (symlinks) on the path, but possibly for other reasons (a device may be mounted twice as read-only). One may or may not want to resolve explicity such symlinks. getting to the end of a chain of symbolic links to a non-symlink file or name. This may or may not yield an absolute path name, depending on how it is done. And one may, or may not want to resolve it into an absolute pathname.

没有选项的命令readlink foo只在其 参数foo是一个符号链接,答案就是它的值 符号链接。后面没有其他链接。答案可能是相对路径: 无论符号链接参数的值是什么。

但是,readlink具有适用于所有对象的选项(-f -e或-m) 文件,并给出一个绝对路径名(没有符号链接的路径名) 由参数实际表示的文件。

这适用于任何不是符号链接的内容,尽管可能存在这种情况 希望使用绝对路径名而不解析中间路径 路径上的符号链接。这是通过命令realpath -s foo完成的

在符号链接参数的情况下,readlink及其选项将 再次解析参数的绝对路径上的所有符号链接,但是 这也将包括可能遇到的所有符号链接 在参数值之后。如果你想要一个 参数符号链接本身的绝对路径,而不是指向任何东西 它可能链接到。同样,如果foo是符号链接,realpath -s foo将 获取一个绝对路径,而不解析符号链接,包括符号链接 给出作为论据的。

如果没有-s选项,realpath的作用与 Readlink,除了简单地读取一个链接以及几个链接的值 其他的事情。我只是不清楚为什么readlink有它的 选项,显然造成了不受欢迎的冗余 realpath。

探索网络并不能说明更多,除了可能会有 跨系统的一些变化。

结论:realpath是最适合使用的命令 灵活性,至少对于这里要求的用途。

如果你想将一个包含相对路径的变量转换为绝对路径,这是可行的:

   dir=`cd "$dir"`

"cd"在不改变工作目录的情况下被回显,因为它是在子shell中执行的。

他们说,除了找到$PWD或(在bash中)找到~+更方便一些。

更新之前的答案使用python 3

to_abs_path() {
  python -c "import os; print (os.path.abspath('$1'))"
}

允许

to_abs_path "./../some_file.txt"