53

我需要检查用户主目录中的文件是否存在,因此使用文件检查:

if ( -e "~/foo.txt" ) {
   print "yes, it exists!" ;
}

即使在用户的主目录下有一个名为foo.txt的文件,Perl 总是抱怨没有这样的文件或目录。当我将“~”替换为/home/jimmy(假设用户是 jimmy)时,Perl 会给出正确的判断。

你能解释一下为什么“~”在 Perl 中不起作用并告诉我 Perl 查找用户主目录的方法是什么?

4

6 回答 6

78

~bash-ism 而不是perl-ism,这就是它不起作用的原因。鉴于您似乎使用的是 UNIX 类型的系统,可能最简单的解决方案是使用$HOME环境变量,例如:

if ( -e $ENV{"HOME"} . "/foo.txt" ) {
    print "yes ,it exists!" ;
}

是的,我知道用户可以更改他们的$HOME环境变量,但我会假设他们知道他们在做什么。如果没有,他们应该得到他们得到的一切:-)

如果您想以正确的方式进行操作,可以查看File::HomeDir,它更懂平台。您可以在以下脚本中看到它的实际效果chkfile.pl

use File::HomeDir;
$fileSpec = File::HomeDir->my_home . "/foo.txt";
if ( -e $fileSpec ) {
    print "Yes, it exists!\n";
} else {
    print "No, it doesn't!\n";
}

和成绩单:

pax$ touch ~/foo.txt ; perl chkfile.pl
是的,它存在!

pax$ rm -rf ~/foo.txt ; perl chkfile.pl
不,它没有!
于 2009-09-25T04:03:33.163 回答
59

我不确定每个人是如何错过File::HomeDir的。这是听起来很容易的艰巨任务之一,因为没有人知道您必须考虑的所有愚蠢的例外。Perl 不附带它,因此您需要自己安装它。

知道主目录后,使用File::Spec构造所需的路径:

 use File::HomeDir qw(home);
 use File::Spec::Functions qw(catfile);

 print "The path is ", catfile( home(), 'foo.txt' ), "\n";
于 2009-09-25T04:53:13.143 回答
19

您可以使用波浪号,glob('~/foo.txt')应该可以。或者你可以使用File::Save::Home模块,它也应该照顾其他系统。

于 2009-09-25T04:34:59.873 回答
11

用户的主目录存储在/etc/passwd. 获取信息的最佳方式是getpw*函数

#!/usr/bin/perl 

use strict;
use warnings;

print "uid:", (getpwuid 501)[7], "\n",
    "name:", (getpwnam "cowens")[7], "\n";

要解决您的具体问题,请尝试以下代码:

if ( -e (getpwuid $>)[7] . "/foo.txt" ) {
   print "yes ,it exists!";
}
于 2009-09-25T04:13:58.697 回答
7

试试File::Path::Expand

于 2009-09-25T04:03:06.930 回答
0

快进到 2020 年,从 5.31.10 版开始,现在 perl 的核心是一个名为File::Glob的模块,它可以解析波浪号,例如:

perl -MFile::Glob=":bsd_glob" -lE 'say File::Glob::bsd_glob( "~john" )'

会产生:/home/john

或者

perl -MFile::Glob=":bsd_glob" -lE 'say File::Glob::bsd_glob( "~/some/folder" )'

会产生:/home/jack/some/folder

File::Glob 模块自 perl v5.6 起就存在,但仅与glob已弃用的子例程一起存在。

于 2021-04-14T09:32:32.630 回答