0

perl にはかなり新しいので、これは最適なコードではない可能性が高いため、投稿しています。私はこれを機能させましたが、より良い方法があるかどうか疑問に思っていました。モジュールをダウンロードする機能がありません。ビルド フォルダー内の最後に変更されたディレクトリを、あるサーバーから別のサーバーにコピーしています。引数により、選択するビルド ディレクトリを選択できます。ありがとう

#!C:\strawberry\perl
use warnings;
use strict;

use File::Copy::Recursive;

my $NewFolder = `(dir /o-d/ad/b \\\\myserver1.name.com\\builds\\$ARGV[0] | head -1)`;
chomp($NewFolder);

 $dir1 = "\\\\myserver1.name.com\\builds\\$ARGV[0]/$NewFolder";
 $dir2 = "\\\\myserver2.name.com\\builds\\$ARGV[0]/Backup/$NewFolder";


File::Copy::Recursive::dircopy $dir1, $dir2 or die "Copy failed: $!";
4

1 に答える 1

3

スラッシュを使用します。コードを読みやすくするだけです。

$dir1 = "\\\\myserver1.name.com\\builds\\$ARGV[0]/$NewFolder";

対。

$dir1 = "//myserver1.name.com/builds/$ARGV[0]/$NewFolder";

また、Perl が実行できるシステム コールを実行しないでください。たとえば、Perl はstatを介してファイルの最終変更日を確認できます。さらに優れているのは、コマンドを非常に使いやすくするFile::statモジュールです。stat

@ARGVプログラムでは使用しないでください。代わりに、変数を@ARGV独自の変数に読み込みます。これにより、プログラムが理解しやすくなり、独自の変数はスコープが制限されています@ARGVが、グローバルです。

最新の規則を使用します。変数名はすべて小文字にし、アンダースコアを使用して単語を区切る必要があります。それは$new_folder$NewFolderです。これは任意ですか?はい。しかし、これはほとんどの Perl 開発者が従う規則です。$newFolderこれは、変数が、、、$NewFolderまたは$newfolderこれらのルールによって であることがわかっているため、疑問に思わないことを意味します$new_folder

最後に、use autodie;ファイル操作が失敗するたびに、これによりプログラムが強制終了されます。これにより、perl はエラープログラミング言語のチェック関数から例外チェック言語に変わります。このように、失敗した IO 操作をチェックする必要があるかどうかを心配する必要はありません。

これは、完全にテストされていない、エラーが発生した例です。

use strict;
use warnings;
use autodie;
use File::Copy::Recursive qw(dircopy); #Optional Module
use File::Stat;

use constants {
    ORIG_SERVER => '//myserver1.name.com/builds',
    TO_SERVER   => '//myserver2.name.com/builds',
};

my $from_directory = shift;

#
# Find newest directory
#
opendir my $dir_fh, ORIG_SERVER . "/$from_directory";
my $newest_directory;

while ( my $sub_directory = readdir $dir_fh ) {
    next if $sub_directory eq "." or $sub_directory eq "..";
    next unless -d $sub_directory;

    if ( not defined $newest_directory ) {
        $youngest_directory = $sub_directory;
        next;
    }

    my $youngest_directory_stat = stat ORIG_SERVER . "/$directory/$newest_directory";
    my $sub_directory_stat = stat ORIG_SERVER . "/$directory/$sub_directory";
    if ( $newest_directory_stat->mtime > $sub_directory_stat->mtime ) {
       $newest_directory = $sub_directory;
    }
}

dircopy ORIG_SERVER . "/$directory/$youngest_directory",
    TO_SERVER . "/$directory/$youngest_directory/backup";

dirあなたのプログラムはさまざまなシステム操作コマンドに依存していたので、私のプログラムはあなたのプログラムよりもずっと長いですhead。代わりに、そのディレクトリの下の各エントリをループに読み込みます。ディレクトリ以外のものはすべて ( next if -d $sub_directory) を投げて、特別なディレクトリ.とを投げ出し..ます。

その後、私statは最も若いディレクトリを見つけるために使用します。これは、私にとっては最新の変更時間を持つディレクトリを意味します。Unix は作成時刻を保存しないことに注意してください。ただし、perlport ctimeによると、Win32 での作成時間はmtime.

を使用しなかった場合File::stat、これの代わりに:

my $youngest_directory_stat = stat ORIG_SERVER . "/$directory/$newest_directory";
my $sub_directory_stat = stat ORIG_SERVER . "/$directory/$sub_directory";
if ( $newest_directory_stat->mtime > $sub_directory_stat->mtime ) {
   $newest_directory = $sub_directory;
}

私はこれを行うことができました:

my $newest = ORIG_SERVER . "/$directory/$newest_directory";
my $sub_dir = ORIG_SERVER . "/$directory/$sub_directory";
if ( stat( $newest )[9] > stat( $sub_dir )[9] ) {
   $newest_directory = $sub_directory;
}

値の配列を返さstatないコマンドは、その配列の要素を単純に使用することもできました。しかし、9は何ですか?数行のコードを節約でき、追加の Perl モジュールを含めることもできますが、.File::stat[9]File::stat

お気づきの点の 1 つは、定数が補間されないことです。つまり、次のようなことを続けなければなりません。

my $youngest_directory_stat = stat ORIG_SERVER . "/$directory/$newest_directory";

ただし、Perlish の黒魔術を使用して、引用符内の定数を補間することができます。

my $youngest_directory_stat = stat "@{[ORIG_SERVER]}/$directory/$newest_directory";

それが役立つことを願っています。

于 2013-06-09T03:26:49.047 に答える