Finding all the links in a Unix file/directory path

Discussion in 'Perl Misc' started by freesoft12@gmail.com, May 12, 2009.

  1. Guest

    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
     
    , May 12, 2009
    #1
    1. Advertising

  2. smallpond Guest

    On May 12, 10:23 am, "" <>
    wrote:
    > 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.
    >


    The test for a symbolic link in perl is: -l $name

    > my @dir_tree = ("mkdir -p b/c",
    > "touch b/c/of3.cpp",
    > "echo 4 > b/c/of3.cpp",
    > "cd b && ln -s c f");
    >


    To make a directory in perl: mkdir $dirname;
    To create a symbolic link in perl: symlink OLDFILE,NEWFILE;
     
    smallpond, May 12, 2009
    #2
    1. Advertising

  3. John Guest

    Looks like my question was not clear:

    In my logfile, i see the following path: /tmp/test_hier/b/f/of3.cpp.
    Since directory 'f' is a symbolic link to directory 'c', the actual
    path is /tmp/test_hier/b/c/of3.cpp.

    I want to copy the orig path /tmp/test_hier/b/f/of3.cpp to my target
    directory: /tmp/copy/ . here is what I want to do:

    1) Copy the actual file /tmp/test_hier/b/c/of3.cpp as /tmp/copy/tmp/
    test_hier/b/c/of3.cpp
    2) Create a link: /tmp/copy/tmp/test_hier/b/f -> /tmp/copy/tmp/
    test_hier/b/c

    Now /tmp/copy/tmp/test_hier/ is the same as /tmp/test_hier/. the
    problems are:

    1) 'realpath' just returns the actual file. It does not return how the
    symbolic link is traced through the directories and the actual file is
    found. I need that information.

    2) there could an arbitrary number of links between the first symbolic
    link file (/tmp/test_hier/b/f/of3.cpp) and the actual file i.e /tmp/
    test_hier/b/f -> /tmp/test_hier/b/d -> /tmp/e -> /home/usr1/of3.cpp.

    The problem: I have 2 paths in my hand: the symbolic link file ( /tmp/
    test_hier/b/f/of3.cpp) and the actual file ( /home/usr1/of3.cpp).

    Do any of you have any idea how to trace the intermediate symbolic
    links?
    Regards
    John
     
    John, May 12, 2009
    #3
  4. John <> wrote:
    >Looks like my question was not clear:
    >
    >In my logfile, i see the following path: /tmp/test_hier/b/f/of3.cpp.
    >Since directory 'f' is a symbolic link to directory 'c', the actual
    >path is /tmp/test_hier/b/c/of3.cpp.
    >
    >I want to copy the orig path /tmp/test_hier/b/f/of3.cpp to my target
    >directory: /tmp/copy/ . here is what I want to do:
    >
    >1) Copy the actual file /tmp/test_hier/b/c/of3.cpp as /tmp/copy/tmp/
    >test_hier/b/c/of3.cpp
    >2) Create a link: /tmp/copy/tmp/test_hier/b/f -> /tmp/copy/tmp/
    >test_hier/b/c


    So, if I understand correctly you want to copy the complete _structure_
    of the the file tree, i.e. if a directory entry was a symlink in the
    original then it should become a symlink in the copy, too.

    I _think_ this is exactly the behaviour of File::Copy::Recursive. At
    least the doc says

    SymLinks
    If your system supports symlinks then symlinks will be copied as
    symlinks instead of as the target file. Perl's symlink() is used instead
    of File::Copy's copy() You can customize this behavior by setting
    $File::Copy::Recursive::CopyLink to a true or false value.

    jue
     
    Jürgen Exner, May 12, 2009
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. RonS
    Replies:
    5
    Views:
    4,420
  2. Sigmathaar
    Replies:
    6
    Views:
    476
    Sigmathaar
    Dec 5, 2005
  3. are Dogue
    Replies:
    1
    Views:
    200
    are Dogue
    May 18, 2011
  4. \A_Michigan_User\

    Various path/path/files.asp all #include this 1 file

    \A_Michigan_User\, Jul 10, 2005, in forum: ASP General
    Replies:
    1
    Views:
    234
    Jeff Cochran
    Jul 10, 2005
  5. Replies:
    8
    Views:
    175
    Rasto Levrinc
    Feb 4, 2005
Loading...

Share This Page