【问题标题】:How can I "look behind" the bash command line argument expansion?如何“查看”bash 命令行参数扩展?
【发布时间】:2010-08-02 16:28:51
【问题描述】:

我希望 Perl 脚本接受通配符 (foo-*.ba?) 作为文件名(然后针对整个目录子树进行处理)。

当然,我可以告诉脚本的用户引用参数 ('foo-*.ba?'),但这并不优雅 - 通配符方法旨在作为传递正则表达式的用户友好替代方案(它们也被接受,当然,必须被引用)。问题是,shell(在我的例子中是 bash)将命令行扩展为与当前目录中的通配符模式匹配的文件,所以我糟糕的脚本会使用 bash 找到的任何东西(通常什么都没有,或者一堆foo-lotsof.baz 等)。

在任何地方都有 bash 的未扩展命令行的副本吗?

【问题讨论】:

  • [按设计] 适用于大多数(如果不是全部)Unix/Linux shell。

标签: perl bash


【解决方案1】:

请不要尝试解决这个问题。更改参数的解释方式由用户在选择引用时完成。即使你可以(而且我知道 bash 中有一些我对此一无所知的钩子可能使它成为可能)你不会以这种方式提供更好的用户体验,你会提供更糟糕的体验。

【讨论】:

  • 投反对票。在没有应用程序端通配符检查可以提供的安全网的情况下执行不可逆的文件操作,没有比这更糟糕的用户体验了。 shell 欺骗应用程序关于它的命令行,我厌倦了人们把这个错误特性称为一个特性。通配符扩展应该是标准 POSIX 库的一部分,而不是 shell。
  • misfeature 或功能,一致性更好(并且满足一致性的期望,实际上更安全,IMO)比其他方式。 “应该”不是问题。
【解决方案2】:

根据 bash 手册页,您可以禁用字符扩展 *, ?和 [ 使用 -f 开关。请参阅路径名扩展。

$ bash -f -c 'ls *'
ls: *: No such file or directory

但是你必须要求你的用户改变他们启动 bash 的方式,或者你必须尝试控制它。它只是在转移问题。

您的程序应该处理 shell 行为,而不是相反。

编辑:作为最后一点,我想指出的是,在 unix shell 中使用单引号是一种常见的做法,以防止扩展。你不应该害怕对自己的脚本做同样的事情。

【讨论】:

    【解决方案3】:

    恐怕没有简单的方法可以解决这个问题。 bash 在执行命令之前扩展通配符。这就是为什么你必须将参数引用到find -name '*.txt'——如果你不 bash 会尝试扩展通配符,你会得到不想要的结果

    【讨论】:

    • 这是正确的。 shell 在你的程序获取它们之前扩展它们,你的程序无法知道输入是由 shell 扩展还是按原样键入的。
    • 你也可以转义,如find -name \\*.txt。但这不会让 OP 更快乐。
    【解决方案4】:

    对于来到这个问题却发现没有任何帮助的人的另一个答案: 考虑一下我防止通配符扩展(通配符)的解决方案,here

    this related answer 中概述了它的症结。

    【讨论】:

      【解决方案5】:

      Bash 扩展通配符,然后将它们传递给程序。这是 bash 的一个特性,它也是 bash 的工作原理,所以我认为您无法找到解决方法。 (有趣的是,Windows 的命令行 shell 不会扩展通配符,因此您必须做一些痛苦的变通方法才能让 Perl 脚本按预期工作。)

      引用文件名是标准的解决方案,Linux 命令行用户应该非常熟悉它。

      其他程序(例如find(1))也存在同样的问题,即需要引用带有通配符的参数。

      (即使你能想出某种方法从你的 Perl 脚本中查询 bash 的命令行历史以在用户键入命令时找到该命令,你仍然会遇到从其他 shell、其他脚本运行脚本的问题,等等)

      【讨论】:

      • 能够扩展可能是一个特性,但不能不扩展是一个错误/错误特性。
      • @Medinoc - 有不扩展的能力。只需将通配符放在引号中即可。
      猜你喜欢
      • 2017-12-05
      • 2016-08-23
      • 2014-01-28
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 2023-03-17
      相关资源
      最近更新 更多