2013-09-25 2 views
0

방금 ​​작성한 새 디렉토리에서 현재 dir에 새로운 dir을 작성하고 adb 로그를 저장하려고합니다. 다음 코드를 시도하지만 어떻게 든 로그를 덮어 씁니다. 모든 로그를 저장하고 덮어 쓰지 않고 저장하려고합니다.dir을 만들고 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(); 

도움을 주시면 감사하겠습니다.

+0

그래서 'tee -a ...'를 사용 하시겠습니까? – mob

답변

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의 요소에 콜론이 포함되어 있지 않은 경우 @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"; 
} 

이 수동 $counter를 증가보다 명확하다.

자신 만의 날짜 형식을 사용하는 것 같습니다. POSIX 모듈에서 strftime 함수를 확인하십시오. 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! 

를, 대신 목록을system에 전달하는 것이 좋습니다 단일 문자열. 이렇게하면 쉘 보간 문제를 피할 수 있습니다. 예 :

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

system에 대한 오류 처리를 수행하십시오. 하나의 가능성은 use autodie qw/:all/입니다.

$new_dir = "adb logs"; - 다른 값을 지정하지 않으므로 mkdir은 결코 다른 디렉토리를 만들지 않습니다. -e-d의 모든 간접 참조는 혼란 스러울뿐입니다.

Windows를 사용하는 경우에만 실제 작업을 수행 할 수 있습니다. 모든 if ($ostype eq 'MSWin32')을 제거하고 다른 OS에서 스크립트가 쓸모 없다면 보석금을 받으십시오. BEGIN { $^O eq 'MSWin32' or die "This script can only be run on Windows" }.


지금 가서이 문제를 해결, 제대로 코드 들여 쓰기, 스크립트의 디버깅을하고 당신은 여전히 ​​그 이후에 문제가있는 경우 돌아와. 좋은 Perl 자습서를 찾으려면 Perl tagwiki의 목록을 확인하십시오.

+0

감사합니다 amon,이 스크립트는 Windows 전용입니다. $ new_rir - "adb logs"이미 존재하지 않는 디렉토리를 한 번 만들고 로그 파일을 저장하려고합니다. – user2526207

+0

로그 파일 $ mainlog_filename은 현재 디렉토리 대신 $ new_dir에 저장해야합니다. – user2526207

+1

@ user2526207 귀하의 스크립트가 실제로 그렇게한다고 가정하지만, 현재 양식으로 말하기는 어렵습니다. 내 "대답"은 주요 문제를 다루지는 않지만 실제 디버깅을 시작하기 전에 해결해야하는 다양한 문제를 나열합니다. 너무 혼란 스럽기 때문에 코드를 이해할 수 없습니다.이 혼란을 제거하면 실제 문제가 분명해질 것입니다. – amon

관련 문제