#! perl -slw use strict; use threads qw[ async ]; use threads::shared; our $DRIVES ||= 'C'; die "Nothing to search for" unless $ARGV[ 0 ]; sub runAndCheck { my( $cmd, $doneRef, $quitNow, $lookfor ) = @_; ## Execute the command and retain the pid my $pid = open CMD, "$cmd |" or die "$cmd : $!"; ## While we haven't been told to quit ## And ther eis still output from teh commands while( not $$quitNow and my $line = ) { chomp $line; ## If the number of keys == the number of true values ## We've found (1 of) everything, so we go home. last if keys %$lookfor == grep $_, values %$lookfor; ## For each of the search terms for ( keys %{ $lookfor } ) { ## Skip it if someone already found it next if $lookfor->{ $_ } and $lookfor->{ $_ } ne '1'; ## If this line contains it if( $line =~ $_ ) { ## Set the quitNow if the value indicates this $$quitNow = ( $lookfor->{ $_ } eq '1' ); ## And record the context. $lookfor->{ $_ } = $line; } } } close CMD; ##Shut the pipe kill 1, $pid; ## Kill the child process $$doneRef = 1; ## Flag we're done } my @cmds = map{ "attrib /s $_:\\* " } split '', $DRIVES; my @dones : shared = ( 0 ) x @cmds; ## Used to indicate when the threads are done my %lookfor: shared; ## Used to pas teh search terms in. and the results out. my $quitNow: shared = 0; ## Used to signal early termination for my $searchTerm ( @ARGV ) { ## look for and remove the trailing 'stopper' flag ## $1 will be defined if it is found. $searchTerm =~ s[(!)?$][]; ## Set the flag true if it was and false otherwise $lookfor{ $searchTerm } = defined $1; } ##start the threads async{ runAndCheck( $cmds[ $_ ], \$dones[ $_ ], \$quitNow, \%lookfor ); }->detach for 0 .. $#cmds; ## Wait until all the reads signal they are done ## Ie. count the number of true values in @done ## and continue waiting while this is less than the number of @cmds sleep 1 while grep( $_, @dones ) < @cmds; ## If we found anything, report it if( grep defined, %lookfor ) { printf "%20s : %s\n", $_, ( $lookfor{ $_ } and $lookfor{ $_ } ne '1' ) ? " was found at '$lookfor{ $_ }'" : " was not found." for keys %lookfor; } else { print "None of @ARGV were found"; } __END__ ## No 'stopper flag', everything is found P:\test>412014 -DRIVES=CDPR junk\.htm$ 412014 copyrght cmd\.exe CMD\.EXE$ CMD\.EXE$ : was found at 'A C:\WINDOWS\SYSTEM32\CMD.EXE' cmd\.exe : was found at 'A C:\Program Files\Classic PhoneTools\inssuitecmd.exe' 412014 : was found at 'A P:\test\412014.pl' junk\.htm$ : was found at 'A P:\test\junk.htm' copyrght : was found at ' R R:\cookbook\copyrght.htm' ## A 'stopper flag' set on an item (that also hapens to be early in the search path) ## and the other thread quit before having found anything P:\test>412014 -DRIVES=CDPR junk\.htm$ 412014 copyrght! cmd\.exe CMD\.EXE$ CMD\.EXE$ : was not found. cmd\.exe : was not found. 412014 : was not found. junk\.htm$ : was not found. copyrght : was found at ' R R:\cookbook\copyrght.htm'