/me wonders why someone wouldn't just use
File::PathConvert to convert relative paths to absolute, resolve symlinks, AND handle cross platform portability...
But anyway, I decided to see if I could write a symlink resolver that returns the absolute path of symlink. As the column
merlyn refers to points out, symlinks can sometimes point to symlinks, so I made sure it can handle that. This is probably not the most efficient technique, but I did write it without refering to any documentation other 'mkdir' (I forgot about the permissions mask parameter...).
I'm not a heavy *nix internals program, so if someone can point out why this way may be a bad idea, I'd like to know. *nix internals is something I'd like to have a little more experience with, but so many projects... so little time.
It will also probably break on a condition where a '/' is embedded in a filename. I don't know if this is absolutely impossible or not, perhaps someone more unix-y can tell me.
Update:Add 's' modified on regex to handle newlines in file names, and add '"./" . ' to readlink() in case symlink pointed to a directory, instead of a file. Also, '/' occuring in a file name is not a concern, per
tilly,
tye and
merlyn.
#!/usr/local/bin/perl -w
use strict;
use Cwd;
sub symlink_resolve
{
my $symlink = "./" . shift;
my ($path, $file);
my $here = getcwd ();
while (-l $symlink)
{
($path, $file) = $symlink =~ m|(.*/)(.*)|s;
chdir ($path) || return undef;
$symlink = "./" . readlink ($file) || return undef;
}
($file) = $symlink =~ m|(?:.*/)(.*)|;
$path = getcwd () || return undef;
chdir ($here) || die;
return "$path/$file";
}
{
#
# Delete it if already exists
#
unlink 'sym.final', 'sym.temp/sym.link1', 'sym.link2', 'sym.temp/sy
+m.link3', 'sym.link4';
rmdir 'sym.temp';
mkdir 'sym.temp', 0777;
open (FH, '>sym.final') || die;
close FH;
#
# Create a symlink: ~/sym.link4 -> ~/sym.temp/sym.link3 -> ~/sym.l
+ink2 -> ~/sym.temp/sym.link1 -> ~/sym.final
#
symlink ('../sym.final', 'sym.temp/sym.link1') || die;
symlink ('sym.temp/sym.link1', 'sym.link2') || die;
symlink ('../sym.link2', 'sym.temp/sym.link3') || die;
symlink ('sym.temp/sym.link3', 'sym.link4') || die;
#
# The test... Should tell us that sym.link4 resolves to sym.final
#
die unless my $file = symlink_resolve ('sym.link4');
print "sym.link4 resolves to $file\n";
#
# Clean up after ourselves
#
unlink 'sym.final', 'sym.temp/sym.link1', 'sym.link2', 'sym.temp/sy
+m.link3', 'sym.link4';
rmdir 'sym.temp';
}
--Chris
e-mail jcwren
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.