我已经对Perl脚本调试做了一些研究,但找不到我要找的东西。
让我在这里解释我的问题。
我有一个Perl脚本,它没有进入最后一个while循环,因为它没有按照指示打印任何内容。
所以,我想知道是否有更简单的方法可以逐个查看所有行,就像我们在shell脚本中看到的那样
set -x
这是我的Perl脚本代码
#!/usr/bin/perl -w
my $ZONEADM = "/usr/sbin/zoneadm list -c";
use strict;
use diagnostics;
use warnings;
system("clear");
print "Enter the app\n";
chomp(my $INS = <>);
print "\nEnter the Symmitrix ID\n";
chomp(my $SYMM = <>);
print "\nEnter the Server\n";
chomp(my $SRV = <>);
print "\nEnter the devices\n";
while (<>) {
if($_ !~ m/(q|quit)/) {
chomp($_);
my $TEMP_FILE = "/export/home/ptiwari/scripts/LOG.11";
open (my $FH, '>>', $TEMP_FILE);
my @arr = split(/:/, $_);
if($arr[3]) {
print $FH "/".$INS."db/".$arr[0]." ".$SYMM." ".$arr[1]." ".$arr[2]." ".$arr[3]."\n";
}
else {
print $FH "/".$INS."db/".$arr[0]." ".$SYMM." ".$arr[1]." ".$arr[2]."\n";
}
undef @arr;
close $FH;
}
else {
exit;
}
}
my $IS_ZONE = qx($ZONEADM|grep -i $SRV|grep -v global);
if($IS_ZONE) {
$IS_ZONE = "yes";
}
else {
$IS_ZONE = "no";
}
open(my $FLH, '<', "/export/home/ptiwari/scripts/LOG.11");
my @lines;
while(<$FLH>) {
my ($GLOBAL_MTPT, $SYM, $SYM_DEV, $SIZE, $NEWFS) = split;
print $GLOBAL_MTPT." ".$SYM." ".$SYM_DEV;
print "\n";
}
我已经尝试了perl -d
,但它没有向我展示任何可以帮助我解决为什么它没有进入while循环的问题。
答案 0 :(得分:5)
您的while(<>)
循环没有合理的终止条件。 /q|quit/
正则表达式是错误的。
如果任何行包含q
或quit
,则退出整个脚本。如果设备说明包含quill
或acquisition
等内容,您也会退出。输入意外q
的效果类似于 Ctrl C 。
完成循环并继续使用脚本的唯一方法是发送EOF。这要求用户将 Ctrl D 打入键盘,或简单地结束文件。然后您的脚本将继续。
这个脚本还有其他一些错误/怪异的东西。
主要批评:(a)全大写变量是非正式保留给Perl和实用模块的。小写或混合大小写变量也可以工作。 (b)您的脚本包含相当多的冗余代码。要么将它重构为sub
,要么重写你的逻辑
这是一个重写的示例,可能更容易调试/可能不包含一些错误。
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use constant DEBUG_FLAG => 1; # set to false value for release
my $zoneadm_command = "/usr/sbin/zoneadm list -c";
my $temp_file_name = "/export/home/ptiwari/scripts/LOG.11";
sub prompt { print "\n", $_[0], "\n"; my $answer = <>; chomp $answer; return $answer }
sub DEBUG { print STDERR "DEBUG> ", @_, "\n" if DEBUG_FLAG }
system("clear");
my $app_name = prompt("Enter the app");
my $symm_id = prompt("Enter the Symmitrix ID");
my $server = prompt("Enter the server name");
print "Enter the devices.\n";
print qq(\tTo terminate the script, type "q" or "quit".\n);
print qq(\tTo finish the list of devices, type Ctrl+D.\n);
open my $temp_file, ">>", $temp_file_name
or die "Can't open log file: $!";
while (<>) {
chomp; # remove trailing newline
exit if /^q(?:uit)?$/; # terminate the script if the input line *is* `q` or `quit`.
my @field = split /:/;
# grep: select all true values
@field = grep {$_} ("/${app_name}db/$field[0]", $symm_id, @field[1 .. 3]);
print $temp_file join(" ", @field), "\n";
}
close $temp_file;
DEBUG("finished the reading loop");
# get the zones with only *one* extra process
my @zones =
grep {not /global/}
grep {/\Q$server\E/i}
map {chomp; $_}
qx($zoneadm_command);
my $is_zone = @zones ? "yes" : "no";
DEBUG("Am I in the zone? $is_zone");
open my $device_file, "<", $temp_file_name or die "Can't open $temp_file_name: $!";
while (<$device_file>) {
chomp;
my ($global_mtpt, $sym, $sym_dev) = split;
print join(" ", $global_mtpt, $sym, $sym_dev), "\n";
# or short: print join(" ", (split)[0 .. 2]), "\n";
}
答案 1 :(得分:0)
你需要这样的东西才能进入剧本:
答案 2 :(得分:0)
您真的可以使用调试器:http://perldoc.perl.org/perldebug.html
但如果您的偏好是像bash -x那样追踪,请看一下这个讨论: http://www.perlmonks.org/?node_id=419653
答案 3 :(得分:0)
Devel::Trace Perl模块旨在模仿shell程序的sh -x
跟踪。
答案 4 :(得分:-2)
尝试从上一个打开的语句中删除“my $”,并从最后一个while语句中删除“$”。或者更好的是,试试这个:
open(my FLH, '<', "/export/home/ptiwari/scripts/LOG.11");
my @lines = <FLH>;
foreach (@lines) {
my ($GLOBAL_MTPT, $SYM, $SYM_DEV, $SIZE, $NEWFS) = split;
print $GLOBAL_MTPT." ".$SYM." ".$SYM_DEV;
print "\n";
}
让我知道结果。