如何在bash中取消符号链接的引用?

47

我怎样才能将bash中的任意给定路径转换为其规范形式,并解除路径中可能包含的任何符号链接的引用?

例如:

~$ mkdir /tmp/symtest
~$ cd /tmp/symtest/
/tmp/symtest$ mkdir -p foo/bar cat/dog
/tmp/symtest$ cd foo/bar/
/tmp/symtest/foo/bar$ ln -s ../../cat cat
/tmp/symtest/foo/bat$ cd ../../
/tmp/symtest$ tree
.
|-- cat
|   `-- dog
`-- foo
    `-- bar
       `-- cat -> ../../cat

6 directories, 0 files

如何获取/tmp/symtest/foo/bar/cat的完整规范路径(即:/tmp/symtest/cat)?


谢谢你。我的搜索技巧没有找到那个问题。 - David Dean
不用担心。我只是因为询问了才知道要找它。 :) - Greg Hewgill
2个回答

71

感谢安迪·斯凯尔顿,似乎答案是readlink -f

$:/tmp/symtest$ readlink -f /tmp/symtest/foo/bar/cat
/tmp/symtest/cat

1
在macOS bash中,readlink命令没有-f选项,该选项用于相关stat命令的格式,该命令与readlink共享一个man页面。在macOS bash中,唯一有效的readlink选项似乎是:-n 不要强制在每个输出片段的末尾出现换行符。 - Lucifer Morningstar

-7
这是一个解析符号链接的函数
它的原始目的是解析由/usr/bin符号链接指向的调用脚本的完整路径
# resolve symbolic links
function resolve_link() {
  local LINK_FILE=${1:-${BASH_SOURCE[0]}}
  local FILE_TYPE=`file $LINK_FILE | awk '{print $2}'`
  local LINK_TO=$LINK_FILE
  while [ $FILE_TYPE = "symbolic" ]; do
    LINK_TO=`readlink $LINK_FILE`
    FILE_TYPE=`file $LINK_TO | awk '{print $2}'`
  done
  echo $LINK_TO
}

BASH_SOURCE_RESOLVED=$(resolve_link)
echo $BASH_SOURCE_RESOLVED

它不使用递归,但我从未在bash中使用过递归。

8
什么?这太复杂了,不必要地复制了标准的“readlink -f”功能。更不用说正确的答案已经在3年前发布了... - cha0site
2
请参考此SO答案:https://dev59.com/UnNA5IYBdhLWcg3wL62x,以获取在没有`readlink -f`的系统(如Mac OS X)上更合理的解决方案。 - cha0site

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接