Reputation: 3347
I have an issue with using abs_path()
. I give this function a valid path, but I get undef
as a return value. The path is read from the command line using the following code.
use warnings;
use strict;
use Data::Dumper;
use Cwd qw();
print scalar @ARGV;
print "\n";
print "$ARGV[0]\n";
print "$ARGV[1]\n";
print "$ARGV[2]\n";
my $val = $ARGV[2];
print "$val\n";
my $result = "";
$result = Cwd::abs_path($val);
print "$result\n";
The perl script is executed as follows:
perl pl_test.pl -results_dir = /home/user123/
I get the following result:
3
-results_dir
=
/home/user123/
/home/user123/
Use of uninitialized value in concatenation (.) or string at pl_test.pl line 16.
I have verified using the debugger that the issue is that $result gets undef
as return value from Cwd::abs_path($val);
. I don't understand why this happens
One of the comments prompted me to do some further testing. What I found is that there is a dependency on a trailing slash, in the following manner:
if the directory does not exist: works without a trailing slash, returns undef
with a trailing slash.
if the directory is a sub directory of a directory that does not exist, always returns undef
if the directory exists, will work in both cases, with or without a trailing slash
Upvotes: 6
Views: 3836
Reputation: 1
realpath of perl don't answer well for patch end with "/", like "/home/"
which realpath of bash answer well,
so if u want to call realpath in perl, pay attention to trim last "/" first.
Upvotes: -1
Reputation: 66883
The Cwd
does use the filesystem so you shouldn't ask it to work with non-existent paths.
I've confirmed the observation that it does in fact give me back a path with a non-existent directory if it is in the directory which does exist (and has no trailing slash!), otherwise not. However, this doesn't mean much as the module's purpose is to work with existing paths.
To work with file names in general, for which files need not exist, use the core File::Spec
perl -MCwd=abs_path -MFile::Spec=rel2abs -wE'
say abs_path(".");
say abs_path("./no/such") // "undef";
say File::Spec->rel2abs("./no/such")
'
This prints
/home/my-user-name undef /home/my-user-name/no/such
The trailing slashes don't affect (meaningful) operations of either modules.
Another useful tool is Path::Tiny, with many methods for a variety of work with existing and non-existing paths.
Upvotes: 4