/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

In reply to (jcwren) RE: (2) Simple file question under linux by jcwren
in thread Simple file question under linux by lindex

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.