来自 coreutils 手册:
某些 GNU 程序(至少 cp 和 mv)允许您在对其进行操作之前从每个源参数中删除任何尾部斜杠。 --strip-trailing-slashes 选项启用此行为。
当源参数可能有尾部斜杠并指定到目录的符号链接时,这非常有用。这种情况实际上很常见,因为在此类符号链接上执行文件名补全时,某些 shell 可以自动附加尾部斜杠。如果没有此选项,例如 mv(通过系统的重命名功能)必须将尾部斜杠解释为取消引用符号链接的请求,因此必须重命名间接引用的目录而不是符号链接。尽管这种行为成为默认行为似乎令人惊讶,这是 POSIX 所要求的并与该标准的其他部分一致。
粗体是否意味着 shell 的文件名扩展会在符号链接后附加斜杠?
您在 Bash 手册或 POSIX 规范中哪里看到了这一点?
最初我认为这取决于命令(而不是 shell)如何解释带或不带尾部斜杠作为其命令行参数的符号链接。
答案1
POSIX 所需的行为是mv
将尾部斜杠解释为取消引用符号链接的请求。也就是说,如果foo
是符号链接,POSIX 规定mv
(像任何其他命令一样)必须解释
mv foo/ bar/
作为移动 指向的目录foo
而不是foo
其本身的请求。这在关于路径名解析:
至少包含一个非斜杠字符且以一个或多个尾部斜杠结尾的路径名应像
.
在路径名中附加一个点字符 ( ) 一样进行解析。
换句话说,foo/
相当于foo/.
。
POSIX 不强制甚至不允许路径名扩展在符号链接后附加斜杠。这是某些 shell 在设置非默认选项时所做的事情。我不知道 bash 是否有这个选项。在克什文中,它是set -o markdirs
. Zsh 也有这个选项,但它只影响目录,而不影响目录的符号链接。
在其他情况下,尾部斜杠自然会出现在参数末尾。对于以斜杠结尾的 glob,该 glob 仅匹配目录和目录的符号链接,并且文件名扩展保留尾部斜杠。因此,mv a*/ /somewhere
移动当前目录中名称以 开头的所有子目录a
,以及当前目录中符号链接的所有目标,使得符号链接以 开头a
并且目标是一个目录。另一案已完成;我不会详细介绍,因为 bash 和 zsh 有很多完成选项,但根据选项的不同,foo/
完成时很容易结束,foo
并且foo
是目录的符号链接。
答案2
粗体是否意味着 shell 的文件名扩展会在符号链接后附加斜杠?
不,这意味着A壳可能如果链接指向一个目录,并且他们提供了 `--strip-trailing-slashes 选项,部分是为了允许用户防止该操作的副作用,那么这样做似乎是合理的。这是您引用的文字的字面意思。
您在 Bash 手册或 POSIX 规范中哪里看到了这一点?
无处可去,因为这不是真的。 POSIX 不指定文件名完成行为。
第二个粗体段落指的是前一句中描述的行为,但您没有加粗,并且POSIX 路径名解析要求以 a 结尾的路径/
必须被视为目录如果可能的话,如果不可能的话会导致错误。它并不是指您加粗的段落中前面不相关的句子。
最初我认为这取决于命令(而不是 shell)如何解释带或不带尾部斜杠作为其命令行参数的符号链接。
事实上,这个选项就是这一事实的一个例子。