#!/usr/bin/perl use strict; use warnings; use IO::Pty; use IO::Select; use POSIX qw(:sys_wait_h); use Data::Dumper; my $timeout = 5; my @cmd=('perl', '-e', 'for(0..2){print qq(TEST $_\n); warn(qq(TTTT $_\n)); sleep(1); }'); my $output=''; # create virtal terminal # imortant for applications with terminal detection! my $pty = IO::Pty->new(); # split in two independent processes my $pid = fork(); # fork failed! die('Fork failed!') unless(defined($pid)); if($pid) { # main process! my $select = IO::Select->new($pty); my $time=time()+$timeout; # wait timeout seconds while($time > time()) { # is process running? if(waitpid($pid, WNOHANG) == 0) { # read if possible $output.=<$pty> if($select->can_read(1)); # do something else print "WAIT\n"; # ... } else { # exit while loop last(); } } # process running? if(waitpid($pid, WNOHANG)==0) { print "TIMEOUT KILL PROCESS\n"; # force exit (softly) kill(9, $pid); $output=''; } } else { # forked process! # virtual terminal client my $slave = $pty->slave(); close $pty; $slave->clone_winsize_from(\*STDIN); $slave->set_raw(); # reopen STDOUT and STDERR open(STDOUT, ">&", $slave); open(STDERR, ">&STDOUT"); close($slave); # start programm with actual process id exec(@cmd); # error??? die("EXEC Failed! ($!)"); } if($output) { print "OUTPUT:\n"; print $output; } else { print "NO OUTPUT!\n"; }