abs_path with the home directory
I created a perl script that uses abs_path
but it doesn't correctly handle the home directory (represented by '~')
EG if I try to call abs_path("~/mystuff");
it returns undef
Can I make abs_path
correctly handle the home directory? 开发者_如何学编程And if not, is there an alternative I can use?
#!/usr/bin/perl
use File::HomeDir;
print File::HomeDir->my_home;
The reason that abs_path
doesn't handle it correctly is that "~" is a shell construct. Perl doesn't know anything about what "~" means - it literally treats it as "a directory named 'tilde'(~) under current working directory".
Any program to which "~" is supplied as a parameter would actually get a real directory path from shell instead.
To be able to use home directories from Perl, on Unix you can use $ENV{HOME}
instead of "~" for your own home directory; or for other users use (getpwnam($user))[7]
; there's no clean cross-platform way to do either.
A second approach is to use shell for dirty work in a system call:
my $expanded_home_dir = `cd ~/mydir/; pwd`;
UPDATE:
First, a very good recipe for outright replacement of tilde-home-strings is in "Perl Cookbook" (2d ed), ch. 7.3 "Expanding tildes in filenames".
Second, as daxim mentioned in comments, since Perl 5.6, CORE::glob()
is actually automatically replaced with File::Glob::bsd_glob()
which supports POSIX's GLOB_TILDE
flag and therefore can expand tildes for you.
Interestingly enough, both bsd_glob (in C code, as per Perlmonks), and File::HomeDir
mentioned wisely by Andrew Clark, use precisely the same logic underneath as the Cookbook's recipe 7.3 ($ENV{HOME}||$ENV{LOGDIR}||(getpwnam($<))[7]
) for Unix environments.
精彩评论