On Feb 3, 7:36 am, filip.sne...@gmail.com (Filip Sneppe) wrote:
> Hi,
>
> I am writing a script that executes external command that may hang.
> I want to capture all output produced by the external command and
> continue with my perl code after a certain execution timeout for the
> external program.
> Since I am running the script on Windows, I cannot use any ALARM
> mechanism.
>
> The best alternative I could come up with is the use of Win32::Job, eg.
>
> use win32::Job;
>
> my $timeout = 10;
> my $job = Win32::Job->new;
> $job->spawn(undef, "iscsicli.exe", (), );
> $job->run($timeout);
>
> print "ok\n";
>
> This particular test hangs for 10 seconds (because the iscsicli.exe
> command without any arguments doesn't return) and then continues.
>
> However, in my final script, I need to capture any output returned
> by the external command, up to the point where the job gets killed,
> and this has proven harder than it initially looked.
>
> What I've tried so far:
>
> - written to a temporary file by using this spawn syntax:
>
> $job->spawn(undef, "iscsicli.exe", (), { stdout => "$$.output.txt" } );
>
> but this creates an empty file, I think because of a lack of
> autoflushing
>
> - tried to redirect STDOUT to a variable before calling the
> spawn() funtion, and enabling autoflush. Doesn't do the trick either,
> and I don't know how to reset STDOUT to the default afterwards.
>
> Could anyone please provide a working piece of code that
> can execute an external command, wait for it to finish yet kill
> the command if it takes too long, and still capture all the output
> (STDOUT and STDERR) up to the last line before it got killed.
> Ideally I would even like to do this without creating any temporary
> files. Thanks in advance!

Not particularly elegant since output is sent  to a file
via backticks but I succeeded in getting test program
output that occurs prior  to a 3 second timeout, eg:

    use strict;
    use warnings;
    use Win32::Job;

    my $job = Win32::Job->new;
    my $timeout = 3;

   $job->spawn( $ENV{PERL},
           'perl.exe -e "system q{c:/temp/test.pl>out.tmp 2>&1}"'
         );
   $job->run($timeout);
   __END__

-----------------------------------------
test.pl:
#!perl
print "line1\n";
sleep 1;
warn "line1 to stderr\n";
sleep 5;
print "lastline\n";

-----------------------------------------
The output file contains:
   line1
   line1 to stderr

--
Charles DeRykus



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to