Have been working on a filesystem comparator for use here at
the office (checking for differences on a remote vs local system)
and as a lark threw this together:
#!/usr/bin/perl -w
use strict;
if (@ARGV == 0) {
print "Usage: $0 <options> directory\n";
exit;
}
my $initial_dir = $ARGV[0];
$initial_dir =~ s/\$//;
###
# Begin by reading the initial directory into the master hash, $h_mast
+er
###
my %h_master;
my $holder;
opendir (INIT, $initial_dir);
my @allfiles = grep !/^\.\.?\z/, readdir INIT;
closedir (INIT);
$h_master{'..'} = '';
foreach (@allfiles) {
$holder = $initial_dir."/".$_;
if (-d $holder) {
$h_master{$_} = read_dir_hash($holder,\%h_master);
} else {
$h_master{$_} = 'File';
}
}
###
# Most of this is just to play with it, but it is kind of neat.
#
# %HoC -> hash of functions. each command has it's own associated sub
+.
#
# ls -> duh, list files in current dir.
# cd -> change dir.
# pwd-> present dir.
# help-> print this.
# exit-> duh.
###
my %HoC = (
ls => \&ls,
help => \&help,
cd => \&cd,
pwd => \&pwd,
exit => sub {exit},
);
my $command = '';
my @args = ();
my $rh_current_dir = \%h_master;
my @a_current_dir = split(/\//,$initial_dir);
while (1) {
print "\nEnter Command\n> ";
$command = <STDIN>;
chomp($command);
($command,@args) = split(/ /,$command);
if ($HoC{lc $command}) {
$HoC{lc $command}->(@args);
} else {
print "Unknown command $command, try help\n";
}
}
sub pwd {
###
# Print the present location in the hash
###
my $dir;
$dir = join '/',@a_current_dir;
print "$dir\n";
}
sub cd {
###
# Change to listed directory by moving up or down the hash
# Make sure to adjust the array holding the current spot
###
my $dir = shift;
my $temp;
if ($dir eq '..') {
pop @a_current_dir;
} else {
push @a_current_dir, $dir;
}
if (($$rh_current_dir{$dir}) && ($$rh_current_dir{$dir} ne "File"))
+ {
$temp = $$rh_current_dir{$dir};
$rh_current_dir = $temp;
} else {
print "$dir is not a directory, please try again.\n";
}
}
sub ls {
###
# list current directory
###
my $holder;
my $sizeof;
foreach (keys(%$rh_current_dir)) {
$holder = join '/', @a_current_dir;
$holder .= '/'.$_;
if (-d $holder) {
$sizeof = '<DIR>';
} else {
$sizeof = -s $holder;
}
print "$_\t\t$sizeof\n";
}
}
sub help {
###
# Print help
###
print "Available Commands:\n";
print "ls \t Directory Listing\n";
print "cd \t Change Directory\n";
print "exit\y Exit Program\n";
}
sub read_dir_hash {
###
# open the next dir, read it into a hash, recurse if necessary.
###
my $fq_dir = shift;
my $rh_parent = shift;
my $holder;
my %h_sub;
opendir (DIR, $fq_dir);
my @allfiles = grep !/^\.\.?\z/, readdir DIR;
closedir (DIR);
$h_sub{'..'} = $rh_parent;
foreach (@allfiles) {
$holder = $fq_dir."/".$_;
if (-d $holder) {
$h_sub{$_} = read_dir_hash($holder,\%h_sub);
} else {
$h_sub{$_} = 'File';
}
}
return \%h_sub;
}
Anyways, I thought it was kind of cool, especially as it took
a lot more effort to do this in C++ when I was in school.
Apologies if it's been posted before.