0

fairly new to perl so this is most likely is not the best code which is why I am posting. I got this to work but was wondering if there is a better way. I do not have the ability to download modules. I am copying the last modified directory in a build folder from one server to another server. The argument allows me to choose which build directory to choose from. Thanks

#!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";

我的程序比你的程序长很多,因为你的程序依赖于各种系统操作命令,比如dirhead不认为这是标准的 Windows 操作系统命令。相反,我将该目录下的每个条目读入我的循环中。任何不是目录的东西,我都会扔掉 ( 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没有File::stat返回值数组的命令,我可以简单地使用该[9]数组的元素。然而,什么是 9?尽管它可以为我节省几行代码,并且包括一个额外的 Perl 模块,但最好使用File::stat.

你注意到的一件事是常量不会插入,这意味着我必须继续做这样的事情:

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 回答