使用标志进行Perl调试

使用标志进行Perl调试,perl,debugging,script-debugging,Perl,Debugging,Script Debugging,因此,我的目标是找到一种简单的方法,在Perl中打开一个标志中的打印语句。在C/C++中,您可以使用#define来选择是否运行某些代码,这是打开和关闭调试打印语句的一种方式。其中,如果定义了#define DEBUG,那么您可以打印一些东西,否则您可以在不使用print语句的情况下运行它。我想知道是否有一种简单的方法可以在Perl中实现这一点 下面是一个如何工作的示例: for($i = 0 ; $i < 10; $i++){ if(debug flag){ p

因此,我的目标是找到一种简单的方法,在Perl中打开一个标志中的打印语句。在C/C++中,您可以使用#define来选择是否运行某些代码,这是打开和关闭调试打印语句的一种方式。其中,如果定义了#define DEBUG,那么您可以打印一些东西,否则您可以在不使用print语句的情况下运行它。我想知道是否有一种简单的方法可以在Perl中实现这一点

下面是一个如何工作的示例:

for($i = 0 ; $i < 10; $i++){
    if(debug flag){
         print some info;
    }
    do operational stuff.
}
2.使用调试打印语句运行

perlScript.pl 
perlScript.pl -debug

或者如果有人有更好的主意,请告诉我

与您的想法类似,但更简洁,请转到stderr,并假设您使用诸如Getopt::Long之类的工具来设置调试CLI选项

warn "debug info:..." if ( $debug );

在perl中,编译时也是运行时。因此,使用
#define
类型语句并没有多大优势

我通常的伎俩是:

my $debug = 0; 
$debug += scalar grep ( "-d", @ARGV ); 
GetOpt
实际上可能是一个更好的计划)

然后使用:

print if $debug;
print $statement if $debug > 2;
这意味着我有一个简单的方法来设置详细度,并且允许我通过增加语句来选择它

有时我会嵌入一个信号处理程序来调整调试级别-

#!/usr/bin/perl

use strict;
use warnings;

my $debug = 0; 
$debug += scalar grep ( "-d", @ARGV ); 

$SIG{'USR1'} = { $debug++ };
$SIG{'USR2'} = { $debug-- };

while ( 1 ) {
    print "Debugging at: $debug\n";
    sleep 1;
}

这更像是我在写什么样的代码的问题——在做
fork
y的东西时,我特别喜欢后者,因为这样我就可以独立地动态地调整每个fork中的调试级别

我通常使用以下样板文件通过登录脚本。您可以从命令行覆盖logbase/log配置位置(或者,更常见的情况是,在部署时将适当的位置设置为默认位置),并在为脚本提供一个或多个-verbose标志时,覆盖该日志和log to screen,使用4个verbose提供屏幕输出。这使您可以轻松地从提供详细标志以获取每个日志输出的调试过渡到将其传递给自定义日志处理程序配置以调试子系统,再过渡到在生产部署中设置日志记录,所有这些都只需最少/无需代码更改

use Getopt::Long;
use Pod::Usage;
use Log::Log4perl qw/:easy/;

my $opts = { logconf        => undef,
             logbase        => 'corp.team.app.appname'
             debug          => 0,
           };

GetOptions ( 'logconf|l=s'       => \$opts->{logconf},
             'logbase=s'         => \$opts->{logbase},
             'verbose|v+'        => \$opts->{debug},  ### debug levels - 0 = off (default), 1 = error, 2 = warn, 3 = info, 4 = debug.
                                                      ### Ignored if a logconf is provided.
           ) or pod2usage(0);

### Initialize logging subsystem
init_logger();

### Usage
logger('app_subsystem')->info('some message...');
logger()->debug('debug message...');


### Initialize logging system
sub init_logger {
    ### If a log configuration is found, and debug was not set, use it
    if (        $opts->{logconf}
         and -e $opts->{logconf}
         and  ! $opts->{debug}
       ) {
        Log::Log4perl->init($opts->{logconf});
    }
    ### Otherwise fall through to easy_init a screen logger based on the verboseness level
    ### Logging off if no config found and no verboseness set
    else {
        my ($min, $max) = ( 0, 4 );
        my %levels;
        @levels{$min .. $max} = ( $OFF, $ERROR, $WARN, $INFO, $DEBUG );
        my $log_level = $opts->{debug};
        if ($log_level < $min) {
            $log_level = $min;
        }
        elsif ($log_level > $max) {
            $log_level = $max;
        }
        Log::Log4perl->easy_init($levels{$log_level});
    }
}

### Shorthand shim sub to get a logger
### Always returns a Log::Log4perl logger object
sub logger {
    my ($category) = @_;
    if ($category) {
        return Log::Log4perl->get_logger($opts->{logbase} . '.' . $category);
    }
    return Log::Log4perl->get_logger($opts->{logbase});
}
使用Getopt::Long;
使用Pod::用法;
使用Log::log4perlqw/:easy/;
my$opts={logconf=>unde,
logbase=>“corp.team.app.appname”
调试=>0,
};
GetOptions('logconf | l=s'=>\$opts->{logconf},
'logbase=s'=>\$opts->{logbase},
'verbose | v+'=>\$opts->{debug},###调试级别-0=关闭(默认),1=错误,2=警告,3=信息,4=调试。
###如果提供了logconf,则忽略。
)或POD2使用率(0);
###初始化日志子系统
init_logger();
###用法
记录器('app_subsystem')->info('some message…');
logger()->debug('debug message…');
###初始化日志系统
子初始化记录器{
###如果找到日志配置,但未设置调试,请使用它
如果($opts->{logconf}
和-e$opts->{logconf}
和!$opts->{debug}
) {
Log4perl->init($opts->{logconf});
}
###否则,请根据详细程度轻松初始化屏幕记录器
###如果未找到配置且未设置详细性,则注销
否则{
我的($min,$max)=(0,4);
我的%水平;
@级别{$min..$max}=($OFF、$ERROR、$WARN、$INFO、$DEBUG);
my$log_level=$opts->{debug};
如果($log_level<$min){
$log_level=$min;
}
elsif($log\u level>$max){
$log_level=$max;
}
Log4perl->easy_init($levels{$Log_level});
}
}
###速记垫片接头以获取记录器
###始终返回Log::Log4perl logger对象
子记录器{
我的($类别)=@;
如果($类别){
返回日志::Log4perl->get_logger($opts->{logbase}.'.$category);
}
返回日志::Log4perl->get_logger($opts->{logbase});
}

到v5.10,您还可以在Perl脚本上使用带有
-p
命令行开关的C预处理器,如中所述


(与
-T
开关类似,
#!perl-p
不会自动在脚本中使用C预处理器,但它会强制您在每次运行脚本时自己显式使用
-p
开关)尽管您必须从文件运行perl程序,而不是使用
-e
选项,但
-s
选项允许您在命令行上指定
main
包变量的值

如果你有一个perl程序

use strict;
use warnings;

our $debug
print $debug, "\n";
并使用命令行运行它

perl -s myprog.pl -debug
然后程序将打印
1

请注意,您可以在程序文件本身的shebang行中指定它,而不是在命令行中使用
-s
,因此如果您的代码看起来像

#!/usr/bin/perl -s

use strict;
use warnings;

our $debug
print $debug, "\n";
那么您的命令行只需要包含

myprog.pl -debug

您还可以考虑使用环境变量:<代码> Debug = 1 Perl perLcript。然后您可以检查调试环境变量(
$ENV{DEBUG}
)并做出相应的完美反应!正是我想要的!所以我使用GetOptions作为命令选项。如果他们输入
-debug
标志,是否有办法使
$debug=1
。因为现在我首先设置
$debug=0
,然后执行
GetOptions(debug=I=>$debug)
。问题是如果他们只是执行'-debug',那么
$debug
仍然设置为0。。。。但如果它们不包含详细设置,我希望将其设置为1。出于某种原因,
grep(“-d”,@ARGV)
对我不起作用,它只提供了参数总数。为了计算传递的
-d
参数的数量,我必须使用
grep(/-d/,@ARGV)
。也就是说,使用
/
而不是
。这是假设您使用
script.pl-d-d filename.txt调用脚本,以获得两个调试级别。或者我是否误解了脚本的调用方式(当使用
grep(“-d”…
),即如何使用参数触发调试?问题是如何设置<
myprog.pl -debug