如何使用 /usr/bin/env perl 功能和 perl 参数?
How to use /usr/bin/env perl functionality along with perl arguments?
我有一个带有 shebang 的 perl 脚本
#!/usr/bin/env perl
我希望此脚本在执行时打印每一行。所以我安装了 Devel::Trace 并将脚本 shebang 更改为
#!/usr/bin/env perl -d:Trace
但这会出错,因为它不是有效的语法。
我应该怎么做才能同时使用 env
功能和 tracing
功能?
首先,shebang 行的处理方式因 OS 而异。我在这里谈论的是领先的操作系统 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
就不再起作用,这样的选项就根本无法传递。没机会了。
更灵活的方法是使用这样的 shell 包装器:
#!/bin/bash
exec perl -a -b=123 ... filename.pl
PS:再看你的问题,你一直在问如何和/usr/bin/env perl
一起使用perl开关。没有机会。如果您将选项传递给 Perl,例如 /usr/bin/env perl -w
,Linux 将尝试打开解释器 'perl -w'
。不再分裂。
这是 Just Doesn't Work™ 在某些系统上,尤其是带有 GNU env
的那些东西之一。
这是 perlrun 中提到的一个我过去(滥用)使用过的偷偷摸摸的解决方法:
#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS [=10=] ${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 [=11=] ${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 [=12=] ${1+"$@"}' \
if false
puts "Hello, world!"
希望对您有所帮助!
正如@hek2mgl 评论 above,一种灵活的方法是使用 shell 包装器,因为 shebang 只接受一个参数(这将是 perl
) .一个简单的包装器就是这个
#!/bin/bash
env perl -d:Trace "$@"
你可以像这样使用
#!./perltrace
或者您可以创建类似的脚本,并将它们放在 perl
所在的任何位置。
您可以使用 env
的 -S
选项来传递参数。例如:
#!/usr/bin/env -S perl -w
按预期工作
我有一个带有 shebang 的 perl 脚本
#!/usr/bin/env perl
我希望此脚本在执行时打印每一行。所以我安装了 Devel::Trace 并将脚本 shebang 更改为
#!/usr/bin/env perl -d:Trace
但这会出错,因为它不是有效的语法。
我应该怎么做才能同时使用 env
功能和 tracing
功能?
首先,shebang 行的处理方式因 OS 而异。我在这里谈论的是领先的操作系统 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
就不再起作用,这样的选项就根本无法传递。没机会了。
更灵活的方法是使用这样的 shell 包装器:
#!/bin/bash
exec perl -a -b=123 ... filename.pl
PS:再看你的问题,你一直在问如何和/usr/bin/env perl
一起使用perl开关。没有机会。如果您将选项传递给 Perl,例如 /usr/bin/env perl -w
,Linux 将尝试打开解释器 'perl -w'
。不再分裂。
这是 Just Doesn't Work™ 在某些系统上,尤其是带有 GNU env
的那些东西之一。
这是 perlrun 中提到的一个我过去(滥用)使用过的偷偷摸摸的解决方法:
#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS [=10=] ${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 [=11=] ${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 [=12=] ${1+"$@"}' \
if false
puts "Hello, world!"
希望对您有所帮助!
正如@hek2mgl 评论 above,一种灵活的方法是使用 shell 包装器,因为 shebang 只接受一个参数(这将是 perl
) .一个简单的包装器就是这个
#!/bin/bash
env perl -d:Trace "$@"
你可以像这样使用
#!./perltrace
或者您可以创建类似的脚本,并将它们放在 perl
所在的任何位置。
您可以使用 env
的 -S
选项来传递参数。例如:
#!/usr/bin/env -S perl -w
按预期工作