0

Case 1

If I run below command i.e iperf in UL only, then I am able to capture the output in txt file

@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;

Case 2

When I run iperf in DL mode , as we know server will start listening in cont. mode like below even after getting data from client (Here i am using server and client on LAN)

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

On server side:

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%)

Command prompt does not appear, process is contd...

On client side:

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>

So with this as server is cont. listening and never terminates so can't take output of server side to a txt file as it is going to the next command itself to create a txt file.

So I adopted the alarm() function to terminate the server side (iperf.exe -u -s -p 5001) commands after it received all data from the client.

Here is my code:

#! /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;

I know that with system command I cannot capture the o/p to a txt file. I tried with readpipe() and exec() calls but these were also in vain.

Could someone please take a look and let me know why the iperf.exe -u -s -p 5001 is not terminating even after the alarm call and to take the output to a txt file?


mobrule-- Finally I am able to achieve what I wanted. Below is the code I used, but now it is also giving me an error on each subsequent run...

Error message:

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

Code:

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;

Output:

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%)

Also, when for each run of this "iperf.exe" the process always remains live in Taskmanager, if I kill it manually before each run or change the file for taking output every time, then I am able to run it successfully one after another.

Could you please suggest how I can kill that process (rather than doing it manually from task manager) and get rid of that problem?

I tried to unlink the file used but that did not solve the problem.

5
  • @rockyurock Please make an effort to format your post properly. Commented Apr 2, 2010 at 16:41
  • Without commenting on any other part of your code, note that system does not return the output of the command. You need to use backticks for that. See perldoc.perl.org/functions/system.html Commented Apr 2, 2010 at 16:42
  • 1
    You should print out the $@ to see your error is the alarm or if its something else in your eval, also your using @output and @output_1, if you used strict you'd get a compile error. Commented Apr 2, 2010 at 16:59
  • Hello Tim, one simple doubt, how can i perform some command operation and to take its o/p to a txt file within a timed value using alram() call ? /rocky Commented Apr 2, 2010 at 18:21
  • I am trying to automate this iperf very badly. Can you share the script? Commented Sep 28, 2015 at 7:50

1 Answer 1

1

Since the command might time out, you'll want to save as much output as you can while the command is running. Two ways to do this are:

  1. Save the output to a file and read the file contents after the command finishes or times out:

    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. Run the command with open in -| mode and save as much output as you can while the command is running:

    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);
    };
    

In for a penny, in for a pound.

After figuring out what iperf.exe was and downloading it, I got this script to "work":

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;

I strongly urge you to familiarize yourself with all of the functions and syntax of this code before you try to get too much use out of it.

Sign up to request clarification or add additional context in comments.

8 Comments

i tried, but either way did not work at all Ist way:: my @command_output; eval { $file = "dummy.txt"; $command = "iperf.exe -u -s -p 5001"; $SIG{ALRM} = { die "timeout\n" }; alarm 30; system("$command > $file"); alarm 0; }; if ($@) { #print"$@\n"; warn "$command timed out.\n"; } else { print "$command successful. Output was:\n", @output; } open my $fh, '<', $file; # error handling omitted for brevity @command_output = <$fh>; print $fh @command_output; close $file; i got o/p => iperf.exe -u -s -p 5001 timed out.
second way::no o/p at all #! /usr/bin/perl -w my $command = readpipe("iperf.exe -u -s -p 5001"); my @output;eval {local $SIG{ALRM} = sub { die "Timeout\n" }; alarm 10; #my @output = iperf.exe -u -s -p 5001; #my @output = readpipe("iperf.exe -u -c 192.168.5.101 -p 5001 -b 3600k -t 5"); open my $process, "$command |"; # or open my $process, '-|', $command while (<$process>) {push @output, $_;}alarm 0; open FILE, ">display.txt" or die $!; print FILE @output; close FILE; };if ($@) {#print"$@\n";warn "$command timed out.\n";} else {print "$command successful. Output was:\n", @output;}
@rockyurock: are you using both @command_output and @output? You should use one or the other but not both. I omitted use strict; use warnings; from my examples for brevity, but maybe I should put them in.
@rockyurock Re 1st comment: Don't say print $fh @command_output. $fh is an input filehandle. If you want to print to your screen just say print @command_output
@rockyurock Re 2nd comment: It looks you are writing to the file display.txt inside the eval block? If the command times out you will exit from the block and that code won't get executed. Move it outside the eval block.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.