1

使用 Perl 和 ADB 命令我希望捕获 logcat 日志并同时保存到文本文件(同时在手机上执行手动 PLMN 搜索)。我更熟悉 Python,但由于遗留原因需要我使用 Perl。

在日志捕获期间,我希望在保存/停止捕获日志然后退出之前等待以下 logcat 字符串 >> /EVENT_NETWORK_SCAN_COMPLETED/ <<。

在一些在线指针的帮助下,我在下面的脚本中进行了尝试,但脚本永远不会退出,这使我得出结论,我的方法对于手头的任务可能过于简单。任何人都可以指导我哪里出错了,或者如果这项任务是可能的?谢谢。

  use strict;
  use warnings;
  use diagnostics;

     sleep(5);
     system('adb wait-for-device');
     my $CollectLog = system('adb logcat > logcat.txt');
     my @Lines = split("\n", $CollectLog);

  # process lines
  foreach my $Line ( @Lines )
  {
        if($CollectLog =~ /EVENT_NETWORK_SCAN_COMPLETED/m)
        {
            print "string matches the pattern\n";
            system('adb logcat -d'); 
            last;
        }
  }
4

3 回答 3

1

另一种可能的解决方案是打开 ADB 服务的套接字并通过 shell 命令执行 logcat。然后,您可以使用标准 IO::Handle::getline() 简单地处理输出。

use strict;
use warnings;
use IO::Socket;

# Connect to the local ADB service
my $adbsock = IO::Socket::INET->new('127.0.0.1:5037') || die "Cannot connect to ADB service: $!";
# Connect to the device
my $data = 'host:transport-usb';
$adbsock->write(sprintf("%04X%s",length($data), $data));
$adbsock->read($data, 4);
die "connect connect to USB device" unless $data eq "OKAY";
# Execute logcat
$data = 'shell:logcat';
$adbsock->write(sprintf("%04X%s",length($data), $data));
$adbsock->read($data, 4);
die "Cannot execute logcat" unless $data eq "OKAY";
# Process the lines
my @fifo;
while(defined( my $line = $adbsock->getline())) {
    push @fifo, $line;
    shift @fifo if (scalar(@fifo) > 100);
    if($line =~ /EVENT_NETWORK_SCAN_COMPLETED/) {
        # dump the FIFO queue
        print @fifo;
        last;
    }
}

上面有两个假设:

  1. 本地 ADB 服务运行正常(运行 'adb wait-for-device' 的 OP 方法应该可以做到这一点)
  2. 仅连接了一个设备,并且通过 USB 连接

这里有一个(相当简洁的)对协议的引用以及您可以在此处执行的命令。根据经验,并非所有都完全按照描述工作,所以我建议进行实验。

PS。很抱歉复活了一个老问题,但我遇到了同样的问题,发现这个问题的答案不太适合我的目的。

于 2014-06-28T12:07:16.810 回答
0

有一个模块,称为期望:http ://search.cpan.org/~rgiersig/Expect-1.15/Expect.pod

您的系统分叉并且不返回任何内容的问题。您应该使用反引号,但 expect 更适合这项工作。

  use Expect;
  use Data::Dumper;

  # create an Expect object by spawning another process
  my $exp = Expect->spawn('adb wait-for-device') or die "Cannot spawn 'adb wait-for-device': $!\n";
  ### wait timeout sec or the string 
  $exp->expect($timeout,'-re',/EVENT_NETWORK_SCAN_COMPLETED/);
  ### get everything before this string
  my $CollectLog = $exp->exp_before();
  ### print out
  print Dumper($CollectLog);
  # if no longer needed, do a soft_close to nicely shut down the command
  $exp->soft_close();
于 2013-11-07T15:02:50.887 回答
0

I'd try a piped open to stream the data from 'adb' and then writing the log yourself:

open my $OUT, "> logcat.txt" or die;
open my $IN, "adb logcat |" or die;

while (<$IN>) {
  if (/EVENT_NETWORK_SCAN_COMPLETED/) {
    `adb logcat -d`
    last;
  }
}
close $OUT;
close $IN;

I'm not sure about this working under Windows, though.

A (lousy) fallback would be to start the log writing in one process, then continually open the file for reading seek to your last position, and read to the end searching for your halt-string.

于 2014-01-14T04:31:49.120 回答