【问题标题】:How to use /usr/bin/env perl functionality along with perl arguments?如何使用 /usr/bin/env perl 功能和 perl 参数?
【发布时间】:2018-04-26 04:54:45
【问题描述】:

我有一个带有 shebang 的 perl 脚本

#!/usr/bin/env perl

我希望这个脚本在执行时打印每一行。所以我安装了 Devel::Trace 并将脚本 shebang 更改为

#!/usr/bin/env perl -d:Trace

但这会产生错误,因为它不是有效的语法。

如何同时使用env 功能和tracing 功能?

【问题讨论】:

    标签: linux perl environment-variables trace


    【解决方案1】:

    这是在某些系统上Just Don't Work™的其中一种情况,尤其是那些带有 GNU env 的系统。

    这是perlrun 中提到的一个偷偷摸摸的解决方法,我过去(ab)使用过:

    #!/bin/sh
    #! -*-perl-*-
    eval 'exec perl -x -wS $0 ${1+"$@"}'
      if 0;
    
    print "Hello, world!\n";
    

    这将在您的 PATH 中找到 perl,您可以将任何其他您想要的开关添加到命令行。您甚至可以在调用perl 之前设置环境变量等。一般的想法是sh 运行eval,但perl 不运行,额外的粗糙位确保Perl 正确找到您的程序并传递所有参数。

    #!/bin/sh
    FOO=bar; export FOO
    
    #! -*-perl-*-
    eval 'exec perl -d:Trace -x -wS $0 ${1+"$@"}'
      if 0;
    
    $Devel::Trace::TRACE = 1;
    
    print "Hello, $ENV{FOO}!\n";
    

    如果您以.pl 扩展名保存文件,您的编辑器应该检测到正确的文件语法,但最初的 shebang 可能会丢弃它。另一个警告是,如果脚本的 Perl 部分抛出错误,则行号可能会关闭。

    这个技巧的巧妙之处在于它也适用于 Ruby(可能还有其他一些语言,如 Python,需要额外修改):

    #!/bin/sh
    #! -*-ruby-*-
    eval 'exec ruby -x -wS $0 ${1+"$@"}' \
      if false
    
    puts "Hello, world!"
    

    希望有帮助!

    【讨论】:

    • 这是 perl 的方法 ;)
    【解决方案2】:

    首先,shebang 行的处理方式因操作系统而异。我在这里谈论的是领先的操作系统 GNU/Linux。 ;)

    shebang 行将只分成两部分,解释器 (usr/bin/perl) 和第二个参数,它应该是文件名参数,它本身将在执行 shebanged 文件时自动附加。一些口译员需要这个。比如#!/usr/bin/awk -f。文件名参数前面需要-f

    Perl 不需要 -f 来传递 perl 文件名,这意味着它的工作方式类似于

    perl file.pl
    

    而不是

    perl -f file.pl
    

    这基本上为您提供了一个可以选择的参数开关的空间,例如

    #!/usr/bin/perl -w
    

    启用警告。此外,由于 perl 使用 getopt() 来解析命令行参数,而 getopt() 不需要用空格分隔参数开关,因此只要不分隔它们,您甚至可以传递多个开关,如下所示:

    #!/usr/bin/perl -Xw
    

    好吧,一旦一个选项接受了一个值,比如-a foo,它就不再起作用了,这样的选项根本就不能被传递。没有机会。

    更灵活的方法是使用这样的外壳包装器:

    #!/bin/bash
    exec perl -a -b=123 ... filename.pl
    

    PS:再看你的问题,你一直在问如何将perl开关与/usr/bin/env perl一起使用。没有机会。如果您将选项传递给 Perl,例如 /usr/bin/env perl -w,Linux 将尝试打开解释器 'perl -w'。没有进一步的分裂。

    【讨论】:

    • 除了你的建议没有其他选择?
    • 不,很遗憾没有其他选择。顺便说一句,您使用的是哪个操作系统? (寻找正确的文档链接)
    • 好吧,实际上,由于 Perl 不需要 -f,这意味着它接受一个没有选项的文件名参数,所以你可以只容纳一个参数。
    • 我使用的是 Ubuntu
    • warnings pragma 无论如何都比-w 命令行选项更有用,所以这里的shebang-line 有另一个节省。
    【解决方案3】:

    作为@hek2mgl cmets above,一种灵活的方法是使用外壳包装器,因为shebang 承认单个参数(将是perl)。一个简单的包装器就是这个

    #!/bin/bash
    
    env perl -d:Trace "$@"
    

    你可以像这样使用它

    #!./perltrace
    

    或者您可以创建类似的脚本,并将它们放在perl 所在的任何位置。

    【讨论】:

      猜你喜欢
      • 2012-10-07
      • 2011-11-28
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      相关资源
      最近更新 更多