如果不存在日志文件,则在Perl中创建一个目录。

18

我有一个 Perl 脚本,需要传入几个参数才能执行。它的执行方式如下:

exec myscript.pl --file=/path/to/input/file --logfile=/path/to/logfile/logfile.log

我在脚本中有以下这行代码:

open LOGFILE, ">>$logFilePath" or die "Can't open '$logFilePath': $!\n";

如果命令行中存在路径$logfilePath,但不存在logfile.log文件,则脚本会创建该文件(这是期望的操作)。但是,如果没有这样的路径,则无法启动。我该如何使脚本在运行之前创建日志文件的路径,如果路径不存在?


一个简单的 mkdir -p 命令将会自动创建所有必要的父级目录。 - Konerak
问题在于我是从别人那里继承了这个文件。我对Perl完全没有任何经验。我非常感激能够得到完整的代码。 - user1546927
用户:在Perl中调用Unix命令可以使用system命令。将其与我上面给出的mkdir命令结合起来使用。 - Konerak
6
为什么要调用Unix命令,而Perl有自己的mkdir函数可以完全完成相同的任务? - dan1111
2个回答

31

假设您有日志文件的路径(可能包括文件名:logfile.log或不包括)存储在变量$full_path中。然后,如果需要,您可以创建相应的目录树:

use File::Basename qw( fileparse );
use File::Path qw( make_path );
use File::Spec;

my ( $logfile, $directories ) = fileparse $full_path;
if ( !$logfile ) {
    $logfile = 'logfile.log';
    $full_path = File::Spec->catfile( $full_path, $logfile );
}

if ( !-d $directories ) {
    make_path $directories or die "Failed to create path: $directories";
}

现在,$full_path 将包含 logfile.log 文件的完整路径。路径中的目录树也将被创建。


7
更新:正如Dave Cross指出的那样,mkdir只能创建一个目录。因此,如果您想一次性创建多个级别,则此方法不适用。
请使用Perl的mkdir命令。示例:
#Get the path portion only, without the filename.
if ($logFilePath =~ /^(.*)\/[^\/]+\.log$/)
{
    mkdir $1 or die "Error creating directory: $1";
}
else
{
    die "Invalid path name: $logFilePath";
}

使用perl自带的函数比运行unix命令更好。
编辑:当然,你应该首先检查目录是否存在。使用-e检查某个东西是否存在。将此添加到上面的代码中:
#Get the path portion only, without the filename.
if ($logFilePath =~ /^(.*)\/[^\/]+\.log$/)
{
    if (-e $1) 
    {
        print "Directory exists.\n";
    }
    else
    {
        mkdir $1 or die "Error creating directory: $1";
    }
}
else
{
    die "Invalid path name: $logFilePath";
}

3
mkdir() 的问题在于一次只能创建一个层级的目录。如果可能会创建多个层级(通常是这样的),那么使用 File::Path 的 make_path() 更好。请注意,make_path() 不仅可以创建多个层级的目录,还可以递归地创建整个路径中缺失的目录。 - Dave Cross
@Dave,感谢您的澄清。我以为我已经测试过多个级别了,但回顾一下我的测试,发现我的测试有误。 - dan1111
1
@dan1111 为什么要先检查目录是否存在?如果不存在,mkdir() 不会默默地失败吗? - lribinik
选择器“-e”将为文件返回“true”,如果我们想要递归检查目录是否存在,我建议使用“-d”。 - Xerix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接