Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

comment on

( [id://3333] : superdoc . print w/replies, xml ) Need Help??

You can set an alarm and then time-out after blocking for awhile. Or you could do your reads non-blocking, and iterate until time is up. With a little effort you can also continue doing other work while processing your input. The following example reads from a program that outputs "ping" every few seconds. But when there's no input to read, it does other things (outputs a dot). And when a "ping" is detected, it responds by outputting a "pong".

#!/usr/bin/env perl use strict; use warnings; use Time::HiRes qw(usleep); use IO::Select; use File::Spec::Functions qw(catfile); use constant USLEEP_TIME => 25_000; # Microseconds use constant RUN_TIME => 30; # Seconds my $cmd = catfile((getpwnam($ENV{USER}))[7],'scripts','outputter'); # +This just sets up the path to the external script. You could hard-cod +e it or base it on FindBin if you want. open my $r, '-|', $cmd or die $!; my $s = IO::Select->new($r); __PACKAGE__->run( {read => $r, select => $s, ping => 0}, [ sub { my $self = shift; $self->{select}->can_read(0) } => sub { my $self = shift; my $ifh = $self->{'read'}; chomp(my $i = <$ifh>); print "\n<$i>\n"; $self->{ping} = 1; } ], [ sub { my $self = shift; !$self->{ping}; } => sub { usleep USLEEP_TIME; print "."; STDOUT->flush; } ], [ sub { my $self = shift; $self->{ping}; } => sub { my $self = shift; print "(pong)\n"; $self->{ping} = 0; } ], ); sub run { my ($class, $args) = (shift(), shift()); $args ||= {}; my $s = bless $args, $class; my $time = time(); while(time() < $time + RUN_TIME) { foreach my $step (@_) { $step->[1]->($s) if $step->[0]->($s); } } }

The ping script can look like this:

#!/usr/bin/env perl use strict; use warnings; use IO::Handle; STDOUT->autoflush(1); while (1) { print STDOUT "ping\n"; sleep 2; }

Using a poor-man's event loop (the while loop), and by taking care to not let the "handlers" block, this script is able to accept input and when there's no input spend time doing other things.

When this script exits, the pipe closes and the ping script will receive a signal to terminate.

This is written with Linux in mind. I don't know if it would work for Windows, and don't have a Windows environment to test on anymore.


In reply to Re: Run and kill external programm after x seconds by davido
in thread Run and kill external programm after x seconds by demichi

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.