截断源自全局模式匹配的路径中的多个斜杠的行为

截断源自全局模式匹配的路径中的多个斜杠的行为

从我有限的研究看来,在 bash 中,全局模式后面的任何多个斜杠都会被截断,如下所示:

echo ////[h]ome////user////Desktop////test////
# outputs ////home/user/Desktop/test/

echo ////home////user////Desktop////tes[t]////
# outputs ////home////user////Desktop////test/

这个结论正确吗?这种行为有定义吗?如果是的话,在哪里?它在不同的 shell 之间共享吗?有什么相关性吗?

我已经阅读了 bash 手册,但找不到任何关于此的内容,尽管我可能错过了一些东西。我知道这些符号之间没有语义差异(除了前导双斜杠的例外),只是不知道这种行为是否是有意的或有目的的。

编辑:所描述的行为发生在 Ubuntu 上的默认 bash 中。 Korn shell ( /usr/bin/sh) 没有截断任何斜杠。

编辑2:只是为了澄清:

  • 我不是问Linux如何处理多个斜杠,很明显,除了前导双斜杠异常之外的多个斜杠没有语义意义,可能会被截断。
  • 我不是在问这种行为如何影响 shell 管道中的任何内容 - 显然不会,除了如果全局扩展作为参数传递下去,它只是有更多的斜杠。
  • 我不是问为什么这种情况会发生在具有 glob 模式的路径上 - 很明显,无论处理 glob 扩展的任何代码也会截断 glob 后面的斜杠。
  • 我特意问一下是否定义了此行为,有意或有目的地在不同的 shell 之间共享。

答案1

一些发现:

  • 该行为(删除一些多余的斜杠)是明确地允许通过 POSIX

    路径名中的字符应使用显式匹配一个或多个 图案中的字符

    我认为我们不能从该文本中推断出它是必需的

  • 我发现的唯一可以做到这一点的其他 shell 是fish.它甚至更进一步:

    $ fish -c 'echo //hom?///stephane///.'
    /home/stephane/.
    

    csh、、、、、、、、、、、、、都不这样做。tcshdash​​​​​​ksh93mkshyashzshboshrcesakanga

    我没有测试过任何glob()实现。

  • bash 1.13.1(我能够运行的最早版本)已经表现得像这样。

  • ksh 是 shell,它是 sh 的 POSIX 规范的基础,shell bash 复制了其中的大部分功能,但它的行为却并非如此。

  • bash 参考手册指出匹配文件名时,斜杠字符必须始终与模式中的斜杠显式匹配,但在其他匹配上下文中,它可以与特殊模式字符匹配,如下所述,这并不能证明删除多余的/s 是合理的。

所有这些都表明这可能是一次无意的实施事故。 POSIX 不要求它。据我所知,没有其他类似 Bourne/POSIX 的 shell 可以做到这一点。 IMO,这是不可取的,因为生成的文件名最终可能与模式不匹配(case例如在构造中)。

这意味着您不能依赖该行为或脚本中没有该行为sh。在脚本中依赖它bash可能无法适应未来的情况。


¹ 尽管还有其他原因导致 glob 可能生成与 中的模式不匹配的路径名foo[a/b]bar*

相关内容