#!/tools/xgs/perl/5.8.8/bin/perl -w use strict; use lib '/home/fisusr/perl-packages/'; use Benchmark; use Getopt::Long; use Data::Dumper; use POSIX ":sys_wait_h"; $| = 1; my %children; my $max = 16; # monitor child processes $SIG{CHLD} = sub { local ($!, $?); my $pid = waitpid(-1, WNOHANG); return if $pid == -1; return unless defined $children{$pid}; delete $children{$pid}; unless (kill 0 => $pid) { print "Killed child $pid\n"; } }; my $dest = "/scratch/du/sb"; my @dirs; my @skip; my $help = 0; my $limit; GetOptions( 'max=i' => \$max, 'dest=s' => \$dest, 'limit=i' => \$limit, 'dir=s' => \@dirs, 'skip=s' => \@skip, 'help' => \$help ); usage() if ($help); if ($max > 16) { print "Maximum number of child processes has been set to $max; proceed? "; chomp(my $ans = <>); unless ($ans =~ /y|yes/i) { print "Exiting ...\n"; exit(1); } } usage("$dest is not a directory") unless (-d $dest); usage("-dir is required") unless (@dirs); foreach my $dir (@dirs) { usage("$dir does not exist!") unless (-d $dir); } my %dirs = map { $_ => 1 } @dirs; my %skip = map { $_ => 1 } @skip; multi_dir(\%dirs,\%skip,$limit); sub multi_dir { my ($dirs,$skip,$limit) = @_; foreach my $dir (keys %$dirs) { if(opendir(my $dh,$dir)) { (my $name = $dir) =~ s/\//_/g; mkdir "$dest/$name" unless (-e "$dest/$name"); my @subs = sort grep { !/^\.+/ && -d "$dir/$_" } readdir($dh); closedir($dh); if ($limit) { @subs = @subs[1 .. $limit]; } my $total = @subs; print "There are $total directories/files to evaluate ...\n"; my $count = 0; foreach my $sub (@subs) { next if (exists $skip->{$sub}); next if ($sub eq $dir); while (keys %children >= $max) { } $count++; die "Cannot fork: $!\n" unless defined(my $child_pid = fork()); if ($child_pid > 0) { $children{$child_pid} = 1; print "There are currently ", scalar(keys %children), " child processes\n"; next; } elsif ($child_pid == 0) { system("/proj/fisdata/fisusr/sandboxes/sasi/tools/diskusagereports_v201/scripts/find.sh $dir/$sub -type d -o -type f > $dest/$name/$sub.dat"); # print "/proj/fisdata/fisusr/sandboxes/sasi/tools/diskusagereports_v201/scripts/find.sh $dir/$sub -type d -o -type f > $dest/$name/$sub.dat"; print "Child [$$] running find.sh on $sub $count/$total\n"; } exit; } } else { warn "Could not read $dir: $!\n"; } } }