kgimpel has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a tool that works like a directory list (ls, dir, etc) and I'd like to report something akin to the absolute path for each of the files. However, I don't want to see mountpoint information and I don't want symlinks resolved.

IE:
According to the file system, my working dir is here:
/base/path/to/a/
if I do a directory listing, I see:
file.txt

If you use the cwd module and check the abs_path of the file, you get
/mountpoint/base/path/linked/to/a/file.txt

(/base is a mountpoint; plus there is a symlink here /base/path/to -> /base/path/linked/to)

Now, of course, I may not actually be inside the directory that I'd like to work with; I might want to call this from "/base", with "path/to/a" as an argument. Can anyone suggest a way for me to report the "unreal" absolute path that would look like this?
/some/base/path/to/a/file.txt

Thanks.

Replies are listed 'Best First'.
Re: unreal absolute path
by zentara (Cardinal) on Nov 28, 2004 at 12:31 UTC
    Without wracking my brain too hard, I think you are looking for File::Spec
    #!/usr/bin/perl use File::Spec; my $abs_path = File::Spec->rel2abs( $rel_path ); my $rel_path = File::Spec->abs2rel( $path, $base );

    I'm not really a human, but I play one on earth. flash japh
Re: unreal absolute path
by gaal (Parson) on Nov 28, 2004 at 08:26 UTC
    If there are several different ways to get to your path, how would you choose which to use? Your shell has that information because it keeps track of where you cd'ed to; but it doesn't communitacate that to anyone else.

    (If you're in /a, and have symlink b -> /c, and type in  cd b ; cd .. -- where do you end up? Different shells do different things here.)

Re: unreal absolute path
by ikegami (Patriarch) on Nov 28, 2004 at 07:29 UTC
    Is there anything wrong with
    my $dir_name = '/base/path/to/a/'; my $dh = DirHandle->new($dir_name) or die("booooo $!\n"); my $file_name; while (defined($file_name = $dh->read())) { my $full_file_name = "$dir_name/$file_name"; ... }
      Not to be obtuse about it, but my whole problem is generating the info for the first line in your solution.

      Now that I consider it, this may be more of a unix question than a perl one. If I run the script from inside a given directory, how do I determine where that dir is located? My unix prompt reports the info in the way I'd like to collect it for the script, but it has already travaeresed symlinks to get there. Perhaps I should be asking for something other than the current working dir?

        Sorry for misunderstanding. I tried a few things...
        $ \ls -ldF /home2/ikegami lrwxr-xr-x ... /home2/ikegami@ -> /home3/ikegami $ \ls -ldF /home3/ikegami drwx--x--x ... /home3/ikegami/ $ pwd /home2/ikegami $ perl -e 'print `pwd`' /home3/ikegami $ perl -e 'print `pwd -L`' /home2/ikegami $ perl -e 'chdir "www"; print `pwd -L`' /home3/ikegami/www $ perl -le 'use Cwd; print cwd;' /home3/ikegami $ perl -le 'use Cwd; print getcwd;' /home3/ikegami $ echo $PWD /home2/ikegami $ perl -le 'print $ENV{"PWD"};' /home2/ikegami $ perl -le 'chdir("www"); print $ENV{"PWD"};' /home2/ikegami $ perl -le 'use Cwd qw( chdir ); chdir("www"); print $ENV{"PWD"};' /home2/ikegami/www

        `pwd -L` seems to work, at the cost of creating a child process and running pwd. It stops working if chdir is used, unfortunately.

        If the calling shell provides $ENV{"PWD"}, you save the spawning cost. Of course, it doesn't change if chdir is used.

        ... unless you use the chdir from Cwd everywhere.

Re: unreal absolute path
by ysth (Canon) on Nov 28, 2004 at 10:29 UTC
    Can't you just construct the name the way you looked it up? So if you are in /base, and you got file.txt in a directory listing of path/to/a/, your path is /base/path/to/a/file.txt.

    If you are wanting to use the actual path used to set the current directory to /base, you might want to check $PWD instead of cwd().