http://www.perlmonks.org?node_id=325809
Category: Utility scripts
Author/Contact Info Brent Dax <brent@brentdax.com>
Description:

For a Web project using Embperl, I have to show a small, fixed set of pages with several different templates (base.epl scripts, essentially, although I used a different extension). I chose to do this by creating hard links between the content files in each directory.

crosslink.pl (or whatever you choose to call it) takes a source directory, a destination directory, and a list of files. It then runs link("sourcedir/filename", "destdir/filename") (or symlink) on each file. This allows me to do things like: crosslink template1 template2 index.epl bio.epl links.epl images/picture.jpg

#!/usr/bin/perl

use strict;
use warnings;

if(@ARGV < 3) {
    print <<"END";
Usage: $0 [options] srcdir destdir file1 [file2 [file3 [...]]]
    Hard links given files in destdir to originals in srcdir.
      Options:
        -s    Use soft links
        -v    Verbose--list each file as it's linked
END
    exit;
}

my %opts;

$opts{pop @ARGV}=1 while $ARGV[0] =~ /^-/;

my($srcdir, $destdir, @files)=@ARGV;

for(@files) {
    do_link("$srcdir/$_", "$destdir/$_") or die "Can't link $srcdir/$_
+ to $destdir/$_: $!";
    print "$srcdir/$_ -> $destdir/$_\n" if $opts{-v};
}

sub do_link {
    if($opts{-s}) {
        return symlink($_[0], $_[1]);
    }
    else {
        return link($_[0], $_[1]);
    }
}
Replies are listed 'Best First'.
•Re: Crosslink
by merlyn (Sage) on Feb 02, 2004 at 11:38 UTC
    For symlinks, that won't work unless the sourcedir is absolute, or calculated properly relative to the destdir. I don't see a disclaimer there for that, so I imagine people will be using it naively in a broken way.

    For example, the following won't work:

    $ mkdir src dst $ touch src/foo $ ln -s src/foo dst/bar
    It doesn't work because the kernel will be trying to find dst/src/foo when dst/bar is referenced. The symlink actually needs to be created non-intuitively as:
    $ ln -s ../src/foo dst/bar
    Perhaps if your code computed the proper relative path from an apparent relative path for symlinks, it'd be more useful.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      D'oh! That's what I get for not testing that bit... *sighs*

      =cut
      --Brent Dax
      There is no sig.

        File::Spec's methods rel2abs() and abs2rel() are a convenient way to handle relative and absolute pathing. Also, why not use one of the Getopt::* modules instead of parsing the flags by hand? The performance might not be quite as good, but it does print a warning when someone types an unknown option.
        «Rich36»