不使用交互式调试器调试Perl脚本

dbf7pr2w  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(174)

我的任务是理解和调试一些用Perl 5编写的遗留代码。基本上,我需要理解到这样的程度:我可以决定是否值得用Python重写它,以匹配我们的代码库的其余部分,并且对于那些不熟悉Perl的不太明显的语法的人来说更可读(至少,或者让它保持原样,尽我们最大的努力在必要的时候做一些小的改变,尽管我们对正在发生的事情有一个不完整的理解。
Perl被调用来处理来自我们组织内部脚本语言的脚本中的一些数据(用于与我们的专有硬件交互)。用专有脚本语言编写的部分类似于shellscript,因为发送到解释器的每一行都将写入日志,因此虽然不像在现代IDE中调试Python那样容易,可以通过检查日志来了解发生了什么。但是Perl作为一种编程语言,只打印/记录您告诉它的内容。所以到目前为止,它有点像一个黑盒子。
我查看了Perl docs,发现有一个命令行选项可以启动调试器-d,沿着一个-Dtls选项可以配置调试器行为(这些是“观察Perl如何执行程序”的推荐选项)。
使用-DDEBUGGING重新编译perl以使用-D开关(您是指-d吗?)
因为它是在专有脚本语言脚本中调用的,如果这个调试器只是一个交互式shell,我认为它不适合这个目的(因为当专有脚本语言脚本运行时,我不能将内容发送到stdin)但是如果它不是交互式的,那么将第二个perl安装添加到服务器进行调试也不是不可能的,因此,如果任何人有这个调试器模式和选项的经验,我将感谢有关的一些反馈。
我非常熟悉Python,所以我知道很多技巧来记录一切或设置调试环境以使用VS代码调试器,但使用Perl,我就不舒服了。
我的问题是:有没有什么简单方法(一个标志或其他东西)调用Perl的方式是,发送到解释器的每个命令都以与shell脚本相同的方式写入控制台/stdout/或日志文件?(而不是使用交互式调试shell)?或者我没有更好的选择,除了花时间浏览这个相当庞大的脚本,并把打印语句到处都是?
感谢您阅读这个冗长的问题。

ttp71kqs

ttp71kqs1#

您可以使用Perl调试器以非交互方式打印执行的每条语句。假设您有一个Perl脚本p.pl,例如:

use feature qw(say);
use strict;
use warnings;

$DB::trace=1;  # <-- turn on AutoTrace from this point..
{
    my $bar = "xyz";
    $bar =~ s/y//;
    say "bar = $bar";
    func1();
}

sub func1 {
    for (1..3) {
        say "1 : $_";
        func2($_);
    }
    say "Done 1";
}

sub func2 {
    my $x = shift;
    my $bar = $x ** 2;
    say "2: $bar";
}

然后执行p.pl,如下所示:

$ PERLDB_OPTS="NonStop=1 AutoTrace=0" perl -d p.pl

main::(p.pl:7):     my $bar = "xyz";
main::(p.pl:7):     my $bar = "xyz";
main::(p.pl:8):     $bar =~ s/y//;
main::(p.pl:9):     say "bar = $bar";
bar = xz
main::(p.pl:10):        func1();
main::func1(p.pl:14):       for (1..3) {
main::func1(p.pl:15):           say "1 : $_";
1 : 1
main::func1(p.pl:16):           func2($_);
main::func2(p.pl:22):       my $x = shift;
main::func2(p.pl:23):       my $bar = $x ** 2;
main::func2(p.pl:24):       say "2: $bar";
2: 1
main::func1(p.pl:15):           say "1 : $_";
1 : 2
main::func1(p.pl:16):           func2($_);
main::func2(p.pl:22):       my $x = shift;
main::func2(p.pl:23):       my $bar = $x ** 2;
main::func2(p.pl:24):       say "2: $bar";
2: 4
main::func1(p.pl:15):           say "1 : $_";
1 : 3
main::func1(p.pl:16):           func2($_);
main::func2(p.pl:22):       my $x = shift;
main::func2(p.pl:23):       my $bar = $x ** 2;
main::func2(p.pl:24):       say "2: $bar";
2: 9
main::func1(p.pl:18):       say "Done 1";
Done 1
e5nqia27

e5nqia272#

您可以使用Devel::DumpTrace模块在Perl脚本中模拟bash -x ...

#!/usr/bin/perl
    # demo.pl: a demonstration of Devel::DumpTrace
    $a = 1;
    $b = 3;
    $c = 2 * $a + 7 * $b;
    @d = ($a, $b, $c + $b);

    $ perl -d:DumpTrace demo.pl
    >>>>> demo.pl:3:        $a:1 = 1;
    >>>>> demo.pl:4:        $b:3 = 3;
    >>>>> demo.pl:5:        $c:23 = 2 * $a:1 + 7 * $b:3;
    >>>>> demo.pl:6:        @d:(1,3,26) = ($a:1, $b:3, $c:23 + $b:3);

有一些设置可以产生或多或少的输出,也有一些方法可以只对感兴趣的代码段打开跟踪。如果你也安装了PPI,它会工作得最好,但没有PPI也会工作。
对于重量较轻并且可能已经安装在系统上的软件,另请参阅Devel::Trace

相关问题