【问题标题】:What does "#! -*-perl-*-" mean?“#!-*-perl-*-”是什么意思?
【发布时间】:2020-05-21 09:59:30
【问题描述】:

在 perl 文档中可以阅读:

#! 的解析开关从任何地方提到“perl”开始 线。序列“-*”和“-”被特别忽略,以便您 如果你愿意的话,可以说

#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
    if 0; to let Perl see the -p switch.

让 Perl 看到 -p 开关。

我对评论感到困惑。 “--perl--”这一行在评论中,shebang 已经被解析了。如果我写:

!/bin/sh
#! -*-python-*-
print 1

它不起作用。另外,那些序列总是被忽略?这是否意味着这类似于'/bin/sh -perl'?这在终端上失败了。

然后它还提到了“-p”开关。但是代码中没有p开关。

【问题讨论】:

    标签: shell perl shebang


    【解决方案1】:

    您的报价未完全复制。文字实际上是说

    #! 开关的解析从其中提到“perl”的任何地方开始 线。 序列-*- 被特别忽略,以便您可以, 如果您愿意,请说

    #!/bin/sh --
    #! -*- perl -*- -p
    eval 'exec perl $0 -S ${1+"$@"}'
        if 0;
    

    让 Perl 看到 -p 开关。

    这里有三件事在起作用。

    • #!/bin/sh shebang 使脚本由sh 运行。如果发生这种情况,eval 'exec ...' 的东西是强制 shexec perl 的黑客。
    • -*- perl -*- 说明符是 Emacs mode string。但它也巧合地触发了下一个行为。
    • 第二个#! 与上一项中的perl 文本一起触发了所描述的选项解析。根据解析规则,模式字符串将被忽略,并且该行末尾的 -p 被拾取为 Perl 的实际选项。

    文档中的前几段也许也应该引用来说明上下文:

    从 Perl 5 开始,始终检查 #! 行是否有开关 因为正在解析该行。 因此,如果你在一台只允许一个参数的机器上 #! 行,或者更糟的是,甚至无法识别 #! 行, 您仍然可以获得一致的开关行为,无论 Perl 是如何被调用的,即使 -x 被用来 找到脚本的开头。

    因为许多操作系统默默地切断内核解释 #! 行的 32 个字符后,可能会传入一些开关 在命令行上,有些可能不是;你甚至可以得到一个- 没有 它的信,如果你不小心的话。你可能想确保 您的所有开关都落在该 32 个字符之前或之后 边界。大多数开关实际上并不关心它们是否被处理 冗余,但获得- 而不是完整的开关可以 导致 Perl 尝试执行标准输入而不是您的脚本。 部分-I 开关也可能导致奇怪的结果。

    ...后来:

    如果#! 行不包含单词“perl”,则名为 在 #! 被执行而不是 Perl 解释器之后。这是 有点奇怪,但它可以帮助那些不做#!的机器上的人, 因为他们可以告诉程序他们的SHELL/usr/bin/perl, 然后 Perl 会将程序分派给正确的解释器 给他们。

    【讨论】:

    • 您的 Perl 文档版本是否真的包含 -p?它已在 2004 中删除。
    • 哦,我刚刚搜索了perlrun。我已经关闭了标签,但 IIRC 页面位于 perl.com
    • 非常感谢您这么长的回答。我怀疑我掌握了一切。所以脚本应该是用perl来执行的。如果不是,那么它将与 sh 一起执行。这将执行第三行,这将使 perl 执行相同的文件。现在。第二行将由 perl 解释,它 不是 一个 shebang。遵循一些 perl 解析逻辑,它将选择标志 p (正如另一个答案所提到的那样,文档中缺少该标志)。是这样吗?不太确定 Emacs 模式字符串在这里扮演什么角色。
    • 是的,sh 绕道是一种跨平台获得一致行为的方法。忽略模式行对任何 Emacs 用户来说都是一种便利。有点像exec sn-p 在sh 和 Perl 中是有效的(但具有不同的语义),允许模式行同时触发 Perl 的选项解析逻辑只是减少样板数量的技巧需要在脚本的开头。
    • 或许应该说这在 Linux 和 Windows 成为可行的平台之前很有用,当时 $gender 是 $gender 并且只有一种可口可乐。
    【解决方案2】:

    这是文档中的错误。脚本中的原始行是

    # -*- perl -*- -p
    

    this pull request

    【讨论】:

      猜你喜欢
      • 2018-03-05
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 2023-03-25
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      相关资源
      最近更新 更多