如何使用/ usr / bin / env perl功能以及perl参数?

时间:2018-04-26 04:54:46

标签: linux perl environment-variables trace

我有一个带有shebang的perl脚本

#!/usr/bin/env perl

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

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

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

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

3 个答案:

答案 0 :(得分:10)

这是某些系统上 Just Not Work™的其中一项,特别是那些具有GNU env的系统。

这是我在perlrun中提到的一个偷偷摸摸的解决方法,我过去曾经使用过这个解决方法:

#!/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!"

希望有所帮助!

答案 1 :(得分:2)

首先,根据操作系统,shebang线的处理方式不同。我在这里谈论GNU / Linux,这是领先的操作系统。 ;)

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

前面需要-f。{/ p>

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

答案 2 :(得分:1)

作为@hek2mgl评论above,一种灵活的方法是使用shell包装器,因为shebang允许一个参数(将是perl)。一个简单的包装就是这个

#!/bin/bash

env perl -d:Trace "$@"

你可以像这样使用

#!./perltrace

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