#! perl -slw use strict; use threads qw[ yield ]; use threads::shared; $|++; my $cmd = $ARGV[ 0 ] || 'diskpart'; my $timeout = 10; my @results = timedCommand( $cmd, $timeout ); if( $results[0] ne '**TIMEOUT**' ) { print "Command returned\n", join '', @results; } else { print "Command timed out after $timeout seconds and returned\n", join '', @results; } sub timedCommand { my( $cmd, $timeout ) = @_; my $pid :shared; my( $thr ) = threads->create( \&pipedCmd, $cmd, $timeout, \$pid ); yield until $pid; sleep 1 while $pid and $timeout--; return $thr->join unless $pid; kill 3, $pid if $pid and $timeout; return '**TIMEOUT**', $thr->join; } sub pipedCmd { my( $cmd, $timeout, $pidref ) = @_; my @results; $$pidref = open my $fh, "$cmd |" or die "$!, $^E"; yield; push @results, $_ while defined( $_ = <$fh> ); undef $$pidref; return @results; } __END__ c:\test>timedCommand.pl Command timed out after 10 seconds and returned **TIMEOUT** Microsoft DiskPart version 5.1.3565 Copyright (C) 1999-2003 Microsoft Corporation. DISKPART> c:\test>timedCommand.pl exit Command returned Microsoft DiskPart version 5.1.3565 Copyright (C) 1999-2003 Microsoft Corporation. DISKPART> Leaving DiskPart... c:\test>timedCommand.pl cd Command returned c:\test