0

我正在尝试在当前目录中创建一个新目录,并将 adb 日志保存在我刚刚创建的新目录中。我正在尝试以下代码,但每次运行它时都会以某种方式覆盖日志。我想保存所有日志而不是覆盖它们。

use POSIX;
use Getopt::Long;
our $timestamp;
our $mainlog_filename;
our $ostype = $^O;
our $ProcessObj;
$SIG{'INT'} = 'INT_handler';
$SIG{'TERM'} = 'INT_handler';
$SIG{'ABRT'} = 'INT_handler';
$SIG{'QUIT'} = 'INT_handler';

if($^O eq 'MSWin32') { 
    $SIG{'BREAK'} = 'INT_handler';
    use Win32::Process;
}

$split_val = join(':', @ARGV[0..(@ARGV-1)]);

@split_val = split(':',$split_val);
$counter=1;
foreach $sno(@split_val)
{
print "Serial Number $counter is $sno\n";
$counter++;
}

# Hash to translate number to month name
my $monthhash = {
    1  => 'Jan',
    2  => 'Feb',
    3  => 'Mar',
    4  => 'Apr',
    5  => 'May',
    6  => 'Jun',
    7  => 'Jul',
    8  => 'Aug',
    9  => 'Sep',
    10 => 'Oct',
    11 => 'Nov',
    12 => 'Dec',
};


$currdir = `pwd`; 
chomp $currdir; # gets current directory
$currdir =~ s/ \/[^\/]+$//; # removes the last / and everything after it
$new_dir = "adb logs";
$perm = 755;


sub makeDir {
  if (-e "$new_dir"){ problem("Directory $new_dir already exists.\n") } # Checks for existing
  mkdir ($new_dir,$perm) || problem("Error making Directory $new_dir\n");
  print "Content-type: text/html\n\n";
  print "$new_dir Directory has been created.\n";
  }
sub main
{
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    $mon  = $mon + 1;
    $mday = sprintf("%02d", $mday) if $mday <= 9;
    my $date    = $monthhash->{$mon}.$mday;
    $timestamp=$date."_".$hour."_".$min;
    foreach $sno(@split_val)
    {
    chomp($sno);
      $mainlog_filename = "adblogs_".$sno."_".$timestamp.".txt";
    }

    makeDir() unless -d $new_dir;

    my $adbcommand_logcat;
    my $adb_install_apk;
    my $adb_install_testapk;

    if($ostype eq 'MSWin32') {
        system("title Android");

        foreach $sno(@split_val)
        {
        chomp($sno);
        print "$sno\n";


        chdir $new_dir;
        $adbcommand_logcat = "start \"Android-Logcat\" cmd /c \"adb -s $sno logcat -v time | tee ".$mainlog_filename."\"";
        chdir $currdir;
        $adb_install_apk = "adb install xyz.apk";
        $adb_install_testapk = "adb install xyzTest.apk";

    $cmd = "adb -s $sno get\-state";
    my $cmdop = qx/$cmd 2>&1/;


    print $cmdop;


      if($cmdop =~ m/device/i) {

            system($adb_install_apk);
            system($adb_install_testapk); 
            system($adbcommand_logcat); 
        }
     else {
        print "Device is offline\n";
    }

    }
}
}
sub terminate
{
    print "\nTerminating script ...\n";
    system("adb kill-server");
   #if($ostype eq 'MSWin32') {
   #   $ProcessObj->Kill(0);
  #  }
    exit 0;
}

sub INT_handler
{
    terminate(); 
    exit 0;
}


main();

任何帮助表示赞赏。

4

1 回答 1

3

这个剧本有很多混乱。

您没有这样做use strict; use warnings;可以帮助您检测和防止常见错误。尽快把它放在每个 Perl 脚本的顶部,并修复它发现的所有错误。如果您添加use diagnostics;,您将获得对每条错误消息的更长解释。

您正在将全局变量与our. 很少有需要这样做的情况。更有可能的是,您需要带有my. 此外,在尽可能紧凑的范围内声明您的变量,并尽可能接近它们的第一次使用。预先声明变量不会增加可读性。

即使一个use语句看起来在一个if中,它也总是被执行。这些语句不受正常控制流的约束,因为它们是在编译时执行的。对于条件加载,请使用ifpragma: use if $^O eq "MSWin32", 'Win32::Process',尽管这种条件加载通常没有帮助。

@ARGV[0..(@ARGV-1)]基本上是一样的东西@ARGV。其他一切都是混淆。(在返回值等中使用时会有所不同,但这与此处无关)。

如果其中没有任何元素@ARGV包含冒号,那么@split_val = split ':', join ':', @ARGV是一种非常奇特的写法@split_val = @ARGV,即复制。如果元素可以包含冒号,那么@split_val = map { split ':' } @ARGV可能会更清晰。

当迭代数组元素索引时,最好迭代索引并访问数组元素:

for my $i (1 .. @array) {
  print "The $i-th element has the value $array[$i-1]\n";
}

这比手动增加 a 更清楚$counter

您似乎正在做自己的日期格式。查看模块strftime中的功能。POSIX您似乎想将日期格式设置为Jan28_19_45. 这可以像

 use POSIX qw/strftime/;

 my $timestamp = strftime '%b%d_%H_%m', localtime;

.当您插入变量时,通常更容易阅读,而不是使用运算符连接字符串。例如"foo ".$bar." baz"可以成为"foo $bar baz". 要分隔变量名,您可以使用花括号:"foo".$bar."baz""foo${bar}baz".

我看不到你在哪里定义了一个problem函数。改为用于die致命错误。

在循环中分配给同一个变量只保留最后一个值:

my $foo;
for my $i (1 .. 3) {
  $foo = $i;
}
# $foo == 3, so let's write my $foo = 3 directly!

|除非您的命令使用诸如or之类的 shell 运算符>,否则最好将列表传递给system而不是单个字符串。这避免了外壳插值问题。例如

system "echo", "|delimited text|", "{m,e,t,a}characters";

做一些错误处理system。一种可能性是use autodie qw/:all/

$new_dir = "adb logs";– 您永远不会分配不同的值,因此mkdir永远不会创建不同的目录。所有这些间接与-eand-d只是令人困惑。

只有在 Windows 上才能进行实际工作。if ($ostype eq 'MSWin32')如果您的脚本在另一个操作系统上无用,请删除所有这些并退出: BEGIN { $^O eq 'MSWin32' or die "This script can only be run on Windows" }.


现在去吧,修复这些问题,正确缩进你的代码,让你的脚本可调试,如果在那之后你仍然有问题,请回来。如果您正在寻找好的 Perl 教程,请查看Perl tagwiki中的列表。

于 2013-09-25T21:01:26.757 回答