#!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: $!";
答案 0 :(得分:3)
使用正斜杠。它只是让你的代码更容易阅读:
$dir1 = "\\\\myserver1.name.com\\builds\\$ARGV[0]/$NewFolder";
VS
$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
,我认为这些命令不是标准的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
的{{1}}命令返回一个值数组,我可以简单地使用该数组的File::stat
元素。但是,什么是9?虽然它可以为我节省几行代码,并且包含一个额外的Perl模块,但最好使用[9]
。
你注意到的一件事是常量不插入,这意味着我必须继续做这样的事情:
File::stat
但是,您可以使用Perlish黑魔法的这一位来在引号内插入常量:
my $youngest_directory_stat = stat ORIG_SERVER . "/$directory/$newest_directory";
希望有所帮助。