Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl using File::Spec to remove .. and . from path

I'm using File::Spec on a Unix system to get the absolute path of a file:

use File::Spec::Functions qw(:ALL);
use strict;
use warnings;
use feature qw(say);

my $file = "../../this/is/a/test";

say rel2abs($file);

This prints out /directory/to/program/../../this/is/a/test. I'd like it to print out /directory/this/is/a/test.

I saw the no_upwards method, and here's the description:

Given a list of file names, strip out those that refer to a parent directory.
(Does not strip symlinks, only '.', '..', and equivalents.)

     @paths = File::Spec->no_upwards( @paths );

However, this didn't seem to work. Instead, I looked at the code in the File::Spec module and found this:

sub no_upwards {
    my $self = shift;
    return grep(!/^\.{1,2}\z/s, @_);
}

So, what does this method do, and how do I get it to work?

If I'm reading this right, this takes a list of directories, and then removes all those directories that are . or ... (According to Perldoc \z means match only at the end of a string).

Is there a platform independent way of collapsing these special directories? What is no_upwards suppose to do, and how do you use it? I tried:

 say no_upwards(rel2abs($file));

Is there another method I should be using?

like image 213
David W. Avatar asked Dec 12 '22 06:12

David W.


1 Answers

In the documentation for canonpath in File::Spec, it says:

METHODS

canonpath

No physical check on the filesystem, but a logical cleanup of a path.

$cpath = File::Spec->canonpath( $path ) ;

Note that this does not collapse x/../y sections into y. This is by design. If /foo on your system is a symlink to /bar/baz, then /foo/../quux is actually /bar/quux, not /quux as a naive ../-removal would give you. If you want to do this kind of processing, you probably want Cwd's realpath() function to actually traverse the filesystem cleaning up paths like this.

So I'd look into using Cwd's realpath() function like it says.

like image 118
Paul Tomblin Avatar answered Jan 07 '23 18:01

Paul Tomblin