web-dev-qa-db-ja.com

ログファイルが存在しない場合は、Perlでログファイル用のディレクトリを作成します

いくつかの引数を取る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はコマンドラインから取得されます。パス/ path/to/logfile /はあるが、logfile.logがない場合は、それを作成するだけです(これは望ましいアクションです)。ただし、そのようなパスがない場合、起動に失敗します。スクリプトを実行する前に存在しないログファイルのパスをスクリプトに作成させるにはどうすればよいですか?

13
user1546927

変数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ファイルへの絶対パスが含まれるようになります。パスのディレクトリツリーも作成されます。

23

更新: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";
}

Unixコマンドを実行するよりも、Perl独自の関数を使用することをお勧めします。

編集:もちろん、最初にディレクトリが存在するかどうかも確認する必要があります。使用する -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";
}
7
dan1111