从符号链接文件夹中识别符号链接

从符号链接文件夹中识别符号链接

假设我位于控制台的子文件夹中,该子文件夹是符号链接(软)文件夹的子文件夹(或孙文件夹等)。

从子文件夹中,如果我ls -la什么都不做,则表明所有文件都位于符号链接文件夹内。

我怎么知道呢?目前,我必须转到父文件夹才能知道这一点。

但这意味着通过测试错误查找,测试所有文件夹的层次结构,直到到达父级(链接)。

答案1

您通过某些符号链接导航到当前工作目录的事实仅由您的 shell(即 Bash)跟踪。引导您到达此处的路径称为逻辑路径,它可以包含目录组件,这些目录组件实际上是目录的符号链接。解析完所有符号链接后的路径称为物理路径。

一种既不是您当前的 Bash 也不是其任何内置工具的工具,当它在 shell 的当前工作目录中作为单独的进程生成时,它自然知道该目录的物理路径,因为物理路径是操作系统的路径与进程关联(/proc/self/cwd对于进程)。该工具可以通过检查PWD其环境中的变量或使用任何检查变量的工具来了解逻辑路径。变量的值来自您的 Bash。

cd在 Bash 中,内置函数pwd可以在物理或逻辑路径上操作,请参阅这个答案pwd这不是内置的(例如/usr/bin/pwd)只能告诉您逻辑路径,因为它检查PWD其环境中的变量。在符号链接目录中比较这些:

$ env pwd -L
/logical/path
$ env pwd -P
/physical/path
$ env --unset=PWD pwd -L
/physical/path

请注意,所有这些pwd都不是内置的;env它本身不是 shell 内置程序,它只能运行pwd可执行文件,不能运行内置程序。通过从PWD环境中移除,我们使pwd -L行为变得像pwd -P

ls不关心PWD环境。物理路径和逻辑路径之间可能存在的差异与所做的事情无关ls。您可能认为它应该有所不同。在问题的第一个版本中,您错误地假设符号链接目录中的所有文件都是符号链接;有了这个假设,很容易进一步假设ls隐藏了这个事实。事实上,ls在某些(物理)目录中,无论什么逻辑路径引导您的 shell 到该目录,都以相同的方式工作。

pwd -P您可以通过将 的输出与 的输出进行比较pwd -L(或直接与)来检测物理路径和逻辑路径之间的差异$PWD。让我们构建一个基本警告ls

function ls (
   p="$(pwd -P)"
   command ls "$@"
   [ "$p" != "$PWD" ] && >&2 printf 'ls: warning: ./ -> %s/\n' "$p"
)

我使用了一个函数,而不是别名,因为alias ls='ls --color=auto'它很常见,我不想破坏它;还因为别名不适用于此。别名极有可能存在,使得语法function ls …比可移植的更好ls () …(后者触发别名)。

这个基本功能并不完善。ls /some/other/dir永远不会警告您/some/other/dir,它会警告您./(如果符号链接),尽管./在这种情况下无关紧要。

无论如何,“我怎么知道我所在的子目录是符号链接目录的(孙…)子目录?”的答案?是:

[ "$(pwd -P)" != "$PWD" ]

答案2

我添加$(pwd -P)到我的 bash 提示符中;这给出了真实的文件夹名称而不是符号链接的名称。ls据我所知,没有任何命令开关可以给你你想要的东西。但至少更改提示可以让您知道当前所在的确切位置。

答案3

基于@ajgringo619

这解决了它:

# includes complete left path
alias ll2='if [[ $(diff <(ls "$PWD" | sed "s|.*|$(ls -d "$PWD/")&|g") <(ls -d "$(pwd -P)/"*) | wc -l) == "0" ]]; then ls -l; else paste -d " -> " <(ls "$PWD" | sed "s|.*|$(ls -d "$PWD/")&|g") /dev/null /dev/null /dev/null <(ls -d "$(pwd -P)/"*); fi'

# or 

alias ls2='if [[ $(diff <(ls "$PWD" | sed "s|.*|$(ls -d "$PWD/")&|g") <(ls -d "$(pwd -P)/"*) | wc -l) == "0" ]]; then ls -l; else paste -d " -> " <(ls "$PWD") /dev/null /dev/null /dev/null <(ls -d "$(pwd -P)/"*); fi'

相关内容