Как я могу получить вывод команды, завершенной вызовом alarm () в Perl? - PullRequest
0 голосов
/ 02 апреля 2010

Дело 1

Если я запускаю команду ниже, т.е. iperf только в UL, то я могу записать вывод в текстовый файл

@output = readpipe("iperf.exe -u -c 127.0.0.1 -p 5001 -b 3600k -t 10 -i 1");
open FILE, ">Misplay_DL.txt" or die $!;
print FILE @output;
close FILE;

Дело 2

Когда я запускаю iperf в режиме DL, как мы знаем, сервер начнет слушать в продолжение. режим как ниже даже после получения данных от клиента (здесь я использую сервер и клиента в локальной сети)

@output = system("iperf.exe -u -s -p 5001 -i 1");

На стороне сервера:

D:\_IOT_SESSION_RELATED\SEEM_ELEMESNTS_AT_COMM_PORT_CONF\Tput_Related_Tools\AUTO
MATION_APP_\AUTOMATION_UTILITY>iperf.exe -u -s -p 5001
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size: 8.00 KByte (default)
------------------------------------------------------------
[1896] local 192.168.5.101 port 5001 connected with 192.168.5.101 port 4878
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
[1896] 0.0- 2.0 sec 881 KBytes 3.58 Mbits/sec 0.000 ms 0/ 614 (0%)

Командная строка не отображается, процесс продолжен ...

На стороне клиента:

D:\_IOT_SESSION_RELATED\SEEM_ELEMESNTS_AT_COMM_PORT_CONF\Tput_Related_Tools\AUTO
MATION_APP_\AUTOMATION_UTILITY>iperf.exe -u -c 192.168.5.101 -p 5001 -b 3600k -t
2 -i 1
------------------------------------------------------------
Client connecting to 192.168.5.101, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size: 8.00 KByte (default)
------------------------------------------------------------
[1880] local 192.168.5.101 port 4878 connected with 192.168.5.101 port 5001
[ ID] Interval Transfer Bandwidth
[1880] 0.0- 1.0 sec 441 KBytes 3.61 Mbits/sec
[1880] 1.0- 2.0 sec 439 KBytes 3.60 Mbits/sec
[1880] 0.0- 2.0 sec 881 KBytes 3.58 Mbits/sec
[1880] Server Report:
[1880] 0.0- 2.0 sec 881 KBytes 3.58 Mbits/sec 0.000 ms 0/ 614 (0%)
[1880] Sent 614 datagrams

D:\_IOT_SESSION_RELATED\SEEM_ELEMESNTS_AT_COMM_PORT_CONF\Tput_Related_Tools\AUTO
MATION_APP_\AUTOMATION_UTILITY>

Так с этим как сервер продолжение. прослушивание и никогда не завершается, поэтому не может передать выходные данные со стороны сервера в текстовый файл, так как он собирается перейти к следующей команде для создания текстового файла.

Итак, я принял функцию alarm() для завершения серверных (iperf.exe -u -s -p 5001) команд после получения всех данных от клиента.

Вот мой код:

#! /usr/bin/perl -w
my $command = "iperf.exe -u -s -p 5001";
my @output;
eval {
    local $SIG{ALRM} = sub { die "Timeout\n" };
    alarm 20;
    #@output = `$command`;
#my @output = readpipe("iperf.exe -u -s -p 5001");
#my @output = exec("iperf.exe -u -s -p 5001");

my @output = system("iperf.exe -u -s -p 5001");
    alarm 0;
};
if ($@) {
    warn "$command timed out.\n";
} else {
    print "$command successful. Output was:\n", @output;
}
open FILE, ">display.txt" or die $!;
print FILE @output_1;
close FILE;

Я знаю, что с помощью системной команды я не могу записать o / p в текстовый файл. Я пробовал с readpipe() и exec() звонками, но они также были напрасны.

Может ли кто-нибудь взглянуть и сообщить мне, почему iperf.exe -u -s -p 5001 не прерывается даже после аварийного вызова и перенести вывод в текстовый файл?


mobrule-- Наконец я могу достичь того, чего хотел. Ниже приведен код, который я использовал, но теперь он также выдает ошибку при каждом последующем запуске ...

Сообщение об ошибке:

The process cannot access the file because it is being used by another process.iperf.exe -u -s -p 5001 successful. Output was:

Код:

my @command_output;
eval { 
    my $file = "abc6.txt";    
    $command = "iperf.exe -u -s -p 5001";
    alarm 10;
    system("$command > $file");
    alarm 0;
close $file;
};
if ($@) {
    warn "$command timed out.\n";
} else {
   print "$command successful. Output was:\n", $file;
}
unlink $file;

Выход:

abc6.txt
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size: 8.00 KByte (default)
------------------------------------------------------------
[1892] local 192.168.5.101 port 5001 connected with 192.168.5.101 port 3553
[ ID] Interval       Transfer     Bandwidth       Jitter   Lost/Total Datagrams
[1892]  0.0- 2.0 sec   881 KBytes  3.61 Mbits/sec  0.000 ms    0/  614 (0%)

Кроме того, когда для каждого запуска этого «iperf.exe» процесс всегда остается активным в Taskmanager, если я убиваю его вручную перед каждым запуском или каждый раз меняю файл для получения выходных данных, то я могу запустить его один за другим.

Не могли бы вы подсказать, как я могу убить этот процесс (вместо того, чтобы делать это вручную из диспетчера задач) и избавиться от этой проблемы?

Я пытался отсоединить используемый файл, но это не решило проблему.

1 Ответ

1 голос
/ 02 апреля 2010

Поскольку время ожидания команды может истечь, во время выполнения команды вы захотите сохранить как можно больше выходных данных. Два способа сделать это:

  1. Сохраните вывод в файл и прочитайте содержимое файла после того, как команда завершится или истечет время ожидания:

    my @command_output;
    eval { 
        $SIG{ALRM} = { die "timeout\n" };
        alarm(30);
        system("$command > $file");
        alarm(0);
    };
    open my $fh, '<', $file;  # error handling omitted for brevity
    @command_output = <$fh>;
    close $fh;     # oops, this said "close $file" before ... not a big deal.
    
  2. Запустите команду с open в режиме -| и сохраните как можно больше выходных данных во время выполнения команды:

    my @command_output = ();
    eval {
        $SIG{ALRM} = { ... };
        alarm(30);
        open my $process, "$command |"; # or open my $process, '-|', $command
        while (<$process>) {
            push @command_output, $_;
        }
        close $process;
        alarm(0);
    };
    

За копейки, за фунт.

После выяснения, что было iperf.exe и загрузки его, я получил этот скрипт для "работы":

use strict;
use warnings;
my $command = "C:/cygwin/usr/local/bin/iperf.exe -u -s -p 25005";
my $file = "abc6.txt";
my ($pid,@command_output);
eval {
    my $process;
    $SIG{ALRM} = sub { 
      kill 'INT', $pid;
      close $process;
      die "timeout\n" 
    };
    alarm(10);
    $pid = open $process, "$command |";
    while (<$process>) {
      push @command_output, $_;
    }
    close $process;
    alarm(0);
};
print "eval block result was: $@\n";
print "Output was:\n------\n",@command_output;

Я настоятельно призываю вас ознакомиться со всеми функциями и синтаксисом этого кода, прежде чем пытаться извлечь из него слишком много пользы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...