3

/home/user当我创建并检查是否存在带有波浪号的目录时,我在我的 Perl 脚本中发现了一个轻微的错误行为,如果我使用完整路径就不会发生这种情况。当我第一次运行这个脚本时,它会创建新目录。当我第二次运行它时,它不识别目录的存在,并尝试第二次创建它:

#!/usr/bin/perl
use strict;

my $outdir = '~/test';
my $cmd = "mkdir $outdir";
unless (-d $outdir) {
  0 == system($cmd) or die "Error creating outdir $outdir\n $?";
}

1;


[~] $ rm test/ -rf
[~] $ perl dir.pl
[~] $ perl dir.pl
mkdir: cannot create directory `/home/avilella/test': File exists
Error creating outdir ~/test
 256 at dir.pl line 7.

如何可靠地处理~在 Perl 中使用波浪号的目录?

4

4 回答 4

11

波浪号被shell解释为你的主目录。

因此,Perl 的-d操作员会看到~与您的 shell 调用'mkdir ~/whatever'(扩展~为 mean )不同的东西(称为 的文件/目录/home/user)。

我会尝试专门使用 Perl 函数来执行您的操作。您将避免产生新进程,并且您的文件访问将以一致的方式执行。

注意 Perl 的mkdir内置函数。另请注意File::Glob模块,它确实执行 ~ 字符的扩展(如果您让用户手动输入目录名称,这可能很有用)

于 2013-08-08T09:55:37.407 回答
5

您可以使用%ENV主目录,它是从 shell 导入的值:

my $home = $ENV{HOME};

您还应该知道这mkdir是一个 Perl 内置函数:

mkdir "$home/test" or die "Cannot create test: $!";
于 2013-08-08T09:56:50.240 回答
4

~system函数调用的 shell 解释。它是~由用户主目录替换的 shell。就 Perl 或内核而言,它~是指具有一个字符名称的文件或目录,就像任何其他字符一样。所以由 完成的测试-d失败,因为没有名为~.

如果您使用 Perl 的内置mkdir函数而不是通过 shell 脚本调用外部命令,那么此时您将遇到错误,因为该目录~不存在。

用户的主目录几乎总是在环境变量中可用HOME。如果您愿意,如果HOME不存在,您可以回退到查询用户数据库,但这是一种异常情况。如果存在,请务必使用HOME环境变量,因为有时更改它以运行具有不同配置文件的程序很有用,并且环境变量在实践中始终可用,而用户数据库可能由于某些配置中的网络故障而不可用(例如 NIS 或 LDAP)。

my $home_directory = $ENV{HOME};
if (!defined $home_directory) {$home_directory = getpwuid($<);}
my $outdir = "$home_directory/test";
unless (-d $outdir) {
    mkdir $outdir or die "Error creating $outdir: $!\n"
}
于 2013-08-08T10:10:02.453 回答
2

您的脚本无法创建存在的目录。这就是您向我们提出的错误:

[~] $ rm test/ -rf
[~] $ perl dir.pl
[~] $ perl dir.pl
mkdir: cannot create directory `/home/avilella/test': File exists
Error creating outdir ~/test
 256 at dir.pl line 7.

问题是您的删除行:

[~] $ rm test/ -rf

是错的。像大多数命令一样,正确的语法是:

[~] $ <command> <options> <parameters>

所以它会是:

[~] $ rm -rf test/
于 2013-08-08T11:06:23.717 回答