F
freesoft12
Hi,
I am working on a Perl script that copies files from a log file. Some
of the files are links. The link however is in an intermediate
directory. For example, in a path /tmp/test_hier/b/f/of3.cpp, the
actual path is /tmp/test_hier/b/c/of3.cpp.
I have attached a DirGen.pm that creates the sample directory
hierarchy and a DirGen.t that prints out the information that the file
is a link.
My Questions:
1) Does anyone know how I can recursively trace the links so that I
copy the "exact" hierarchy? For example, I want to copy *everything*
in /tmp/test_hier underneath /tmp/copy/tmp/test_hier (verbatim).
2) The complication is that there might be arbitrary number of links
between the linked path and the actual path. How can I trace all of
them?
All help is appreciated!
Regards
John
--- DirGen.pm
# this package creates a sample directory structure
package DirGen;
sub new {
my $class = shift;
my $work_dir = shift;
my $self = {};
$self->{working_dir_} = $work_dir;
bless($self,$class);
# create a sample hieararchy underneath $work_dir
my @args = ("rm -rf $work_dir && mkdir -p $work_dir");
system(@args) ==0 or die "system command failed:$?";
# go to the working dir
chdir "$work_dir" or die "system command failed:$?";
# the test directory tree
# $work_dir/
# b/ - f -> c/ # f is a link to directory c/
# c/ - of3.cpp
#
my @dir_tree = ("mkdir -p b/c",
"touch b/c/of3.cpp",
"echo 4 > b/c/of3.cpp",
"cd b && ln -s c f");
$self->generate_test_hier_(\@dir_tree);
# access of3.cpp path via the directory link
my $path = "$work_dir/b/f/of3.cpp";
push(@{$self->{paths_}},$path);
return $self;
}
# This function creates a predefined directory hierarchy
sub generate_test_hier_ {
my $self = shift;
my $dir_tree_cmds = shift;
my @args = ();
foreach my $path (@$dir_tree_cmds) {
my @args = ($path);
system(@args) ==0 or die "system command failed:$?";
}
}
sub get_iterator {
my $self = shift;
my $pos = -1;
return sub {
return undef if ($pos > scalar(@{$self->{paths_}}));
return ${$self->{paths_}}[++$pos];
}
}
1;
----- end of DirGen.pm
------ DirGen.t
eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec
perl -w -S $0 $argv:q' if 0;
# This script tests DirGen.pm
require 5.006; # need perl version 5.6 or higher
use strict; # comment out these two
use diagnostics; # and '-w' switch, once testing is over
use File::Basename;
use Cwd qw(realpath);
use DirGen;
my $dirTreeGen = DirGen->new("/tmp/test_hier");
my $dir_it = $dirTreeGen->get_iterator();
while (my $path = $dir_it->()) {
my $target_dir = dirname($path);
my $orig_dir = realpath($target_dir);# realpath works only with
directories
if ($orig_dir ne $target_dir) {
print "$path is a link, the actual path is $orig_dir/".basename
($path)."\n";
}
}
-------- end of DirGen.t
I am working on a Perl script that copies files from a log file. Some
of the files are links. The link however is in an intermediate
directory. For example, in a path /tmp/test_hier/b/f/of3.cpp, the
actual path is /tmp/test_hier/b/c/of3.cpp.
I have attached a DirGen.pm that creates the sample directory
hierarchy and a DirGen.t that prints out the information that the file
is a link.
My Questions:
1) Does anyone know how I can recursively trace the links so that I
copy the "exact" hierarchy? For example, I want to copy *everything*
in /tmp/test_hier underneath /tmp/copy/tmp/test_hier (verbatim).
2) The complication is that there might be arbitrary number of links
between the linked path and the actual path. How can I trace all of
them?
All help is appreciated!
Regards
John
--- DirGen.pm
# this package creates a sample directory structure
package DirGen;
sub new {
my $class = shift;
my $work_dir = shift;
my $self = {};
$self->{working_dir_} = $work_dir;
bless($self,$class);
# create a sample hieararchy underneath $work_dir
my @args = ("rm -rf $work_dir && mkdir -p $work_dir");
system(@args) ==0 or die "system command failed:$?";
# go to the working dir
chdir "$work_dir" or die "system command failed:$?";
# the test directory tree
# $work_dir/
# b/ - f -> c/ # f is a link to directory c/
# c/ - of3.cpp
#
my @dir_tree = ("mkdir -p b/c",
"touch b/c/of3.cpp",
"echo 4 > b/c/of3.cpp",
"cd b && ln -s c f");
$self->generate_test_hier_(\@dir_tree);
# access of3.cpp path via the directory link
my $path = "$work_dir/b/f/of3.cpp";
push(@{$self->{paths_}},$path);
return $self;
}
# This function creates a predefined directory hierarchy
sub generate_test_hier_ {
my $self = shift;
my $dir_tree_cmds = shift;
my @args = ();
foreach my $path (@$dir_tree_cmds) {
my @args = ($path);
system(@args) ==0 or die "system command failed:$?";
}
}
sub get_iterator {
my $self = shift;
my $pos = -1;
return sub {
return undef if ($pos > scalar(@{$self->{paths_}}));
return ${$self->{paths_}}[++$pos];
}
}
1;
----- end of DirGen.pm
------ DirGen.t
eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec
perl -w -S $0 $argv:q' if 0;
# This script tests DirGen.pm
require 5.006; # need perl version 5.6 or higher
use strict; # comment out these two
use diagnostics; # and '-w' switch, once testing is over
use File::Basename;
use Cwd qw(realpath);
use DirGen;
my $dirTreeGen = DirGen->new("/tmp/test_hier");
my $dir_it = $dirTreeGen->get_iterator();
while (my $path = $dir_it->()) {
my $target_dir = dirname($path);
my $orig_dir = realpath($target_dir);# realpath works only with
directories
if ($orig_dir ne $target_dir) {
print "$path is a link, the actual path is $orig_dir/".basename
($path)."\n";
}
}
-------- end of DirGen.t