Here is a simple script that can turn symlinks into real files/directories. What I use this for is when I want two identical directory structures except for a few files. For example, what I'm using it for right as I write this is to have two versions of a Java application running on my system, but with different configurations. Any changes I make to the common data will be seen in both configurations, but the configurations themselves will be unique. In my case, it's because it's on a Linux box, and I share it to my Windows laptop via Samba, and thus configuration parameters that talk about directories are constantly getting messed up. With this, I have a myapp directory, and then I just did this:
$ ln -s myapp myapp.win $ presto -d myapp.win $ cd myapp.win $ presto *.ini
Now all my configuration is separate, but the program and data are common. Everything else in the myapp.win directory is a symlink. I could save a bit of space on the symlinks by building in a relative directory structure instead of a full path (which also makes everything moveable as a whole structure), but I figured the headache wouldn't be worth it. ;-)

Options are:

-d
presto directories. This way you can just say "presto *" and you'll just get all the files, but "presto -d *" will presto the directories, too.
-h
presto uses hardlinks instead of symlinks when creating subdirs. I assume hardlinks take up less diskspace when maintaining the commonality that if changed, they both get changed. You can still presto hardlinks with this program should you desire to have them separate later. Note that I don't think you can make hardlinks for directories, so those will remain symlinks.
I save this as "presto" in my personal "bin" directory. Working great so far.
#! /usr/bin/perl use strict; use warnings; use Getopt::Std; use File::Copy; use File::stat; use File::Spec; use IO::Dir; use Data::Dumper; my %opt; getopts('dh', \%opt); @ARGV = grep { $_ ne '.' and $_ ne '..' } map { s.[/\\]$..g; $_ } @ARG +V; foreach my $l (@ARGV) { unless (((lstat $l)->nlink() > 1 && -f _) || -l _) { print "$l isn't a link - skipping\n"; next; } if (-d $l) { unless (exists $opt{d}) { print "$l is a directory and -d wasn't specified - skippin +g\n"; next; } my $S = File::Spec->catdir(File::Spec->rel2abs(readlink($l))); unlink $l; mkdir $l; if (fork()) { chdir($l); my $Sdir = IO::Dir->new($S); while (defined (my $f = $Sdir->read)) { my $Sfile = File::Spec->catfile($S, $f); if (exists $opt{h} and -f $Sfile) { # if the hardlink fails, fall back to symlink link $Sfile, $f or symlink $Sfile, $f; } else { symlink $Sfile, $f; } } } } else { my $stat = stat($l); rename $l, "$l.old"; copy("$l.old", $l); unlink "$l.old"; utime $stat->atime, $stat->mtime, $l; chmod $stat->mode | 0200, $l; } } 1 while wait != -1;

In reply to Presto-chango on files [symlinks] by Tanktalus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.