1
votes

Below is the part of my code, my code enters "if loop" with $value =1 and output of the process iperf.exe is getting into my_output.txt. As I am timing out the process after alarm(20sec) time, also wanted to capture the output of this process only.

Then after I want to continue to the command prompt but I am not able to return to the command prompt.

Not only this code itself does not PRINT on the command prompt, rather it is printing on the my_output.txt file

(I am looping this if block through rest of my code)

output.txt

inside value loop2
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size: 8.00 KByte (default)
------------------------------------------------------------
[160] local 10.232.62.151 port 5001 connected with 10.232.62.151 port 1505
[ ID] Interval       Transfer     Bandwidth       Jitter   Lost/Total Datagrams
[160]  0.0- 5.0 sec  2.14 MBytes  3.59 Mbits/sec  0.000 ms    0/ 1528 (0%)
inside value loop3
clue1
clue2
inside value loop4
one iperf completed
Transfer

Transfer Starting: Intent { act=android.settings.APN_SETTINGS }

******AUTOMATION COMPLETED******

Looks like some problem with reinitializing the STDOUT.

I tried to use close(STDOUT); but again it did not return to STDOUT.

Code

if($value)
{    
my $file = 'my_output.txt';

use Win32::Process;

print"inside value loop\n";
# redirect stdout to a file

open STDOUT, '>', $file
  or die "can't redirect STDOUT to <$file> $!";

Win32::Process::Create(my $ProcessObj,
                       "iperf.exe",
                       "iperf.exe -u -s -p 5001",
                       0,
                       NORMAL_PRIORITY_CLASS,
                       ".") || die ErrorReport();

$alarm_time = $IPERF_RUN_TIME+2; #20sec            

print"inside value loop2\n";
sleep $alarm_time;    

$ProcessObj->Kill(0);

sub ErrorReport{
    print Win32::FormatMessage( Win32::GetLastError() );
}

print"inside value loop3\n";
print"clue1\n";
#close(STDOUT);
print"clue2\n";
print"inside value loop4\n";
print"one iperf completed\n";
}

my $data_file="my_output.txt";

open(ROCK, $data_file)|| die("Could not open file!");
@raw_data=<ROCK>; 

@COUNT_PS =split(/ /,$raw_data[7]);
my $LOOP_COUNT_PS_4 = $COUNT_PS[9];
my $LOOP_COUNT_PS_5 = $COUNT_PS[10];

print "$LOOP_COUNT_PS_4\n";
print "$LOOP_COUNT_PS_5\n";

my $tput_value = "$LOOP_COUNT_PS_4"." $LOOP_COUNT_PS_5";
print "$tput_value";
close(ROCK);
print FH1 "\n $count    \| $tput_value \n";
3
Please, please, please put a little effort into formatting and use a spell checker. And there is no such thing called an "if loop".Sinan Ünür

3 Answers

7
votes

You need to save STDOUT before reopening it:

open(SAVE, ">&STDOUT") || die "Can't save STDOUT\n"; 
...
open(STDOUT, ">&SAVE") || die "Can't restore STDOUT\n"; 

You can also use a dynamic variable to "save" STDOUT (but this might require reorganizing your code):

do {
  local *STDOUT;
  open(STDOUT, "...");
  ...
}; # STDOUT is restored here

Finally, you can use backticks to capture the complete output:

$x = `iperf.exe ...`;
5
votes

Use local:

{
    local *STDOUT;
    open STDOUT, '>', $file
        or die "can't redirect STDOUT to <$file> $!";

    Win32::Process::Create(my $ProcessObj,
                       "iperf.exe",
                       "iperf.exe -u -s -p 5001",
                       0,
                       NORMAL_PRIORITY_CLASS,
                       ".") || die ErrorReport();

    $alarm_time = $IPERF_RUN_TIME+2; #20sec            

    print"inside value loop2\n";
    sleep $alarm_time;
    $ProcessObj->Kill(0);
}
2
votes

You might also try select

   open FF,">$filename" or die "error opening $filename for writing: $!";
   print "hi 1\n"; # this goes to stdout
   ...
   select FF;    # sets output to FF
   print "hi 2\n"; # this goes to FF ($filename )
   ...
   select STDOUT; # resets output to STDOUT
   print "hi 3\n"; # this goes to stdout