Я пишу сценарий Perl, который позволяет нам легко перемещать или копировать ОГРОМНЫЙ каталог (возможно, +100 000 подкаталогов) в другое место. Я использую File::Copy::Recursive
для этой цели следующим образом (неполный! Некоторые переменные не определены, но это дает минимальное представление о том, что происходит):
use strict;
use warnings;
use File::Copy::Recursive qw(dircopy dirmove pathrmdir);
$File::Copy::Recursive::CPRFComp = 1;
my ($action, $source_location, $target_location) = @ARGV;
opendir(my $source_handle, $source_location) or die "Can't opendir $source_location: $!\n";
my $directories_found = 0;
while (my $sub_dir = readdir $source_handle) {
unless (-d "$source_location/$sub_dir") {
print STDERR "$source_location/$sub_dir not a dir\n";
next;
}
# Makes sure we only move directories given a pattern defined elsewhere
if ($sub_dir =~ $file_match_regex) {
# $action is an input argument
if ($action eq 'copy') {
dircopy("$source_location/$sub_dir/", "$target_location/")
or die "Cannot copy $source_location/$sub_dir/: $!\n";
} elsif ($action eq 'move') {
dirmove("$source_location/$sub_dir/", "$target_location/")
or die "Cannot move $source_location/$sub_dir/: $!\n";
}
$directories_found = 1;
} else {
print STDERR "$source_location/$sub_dir did not match regex\n";
}
}
if ($action eq 'move') {
# Remove topmost directory
pathrmdir($source_location)
or die "Cannot remove $source_location: $!\n";
}
if (!$directories_found) {
print STDERR "No items found to $action\n";
}
При первом запуске кажется, работает как положено. Возьмите эту команду
perl myscript.pl move source/ /home/otherdir/target/
Выход терминала
source/. did not match regex
source/.. did not match regex
и это все.
Однако, когда я запускаю тот же скрипт в перемещенной папке, все идет не так.
perl myscript.pl move /home/otherdir/target/ /home/failing/target/
/home/otherdir/target/. did not match regex
/home/otherdir/target/.. did not match regex
/home/otherdir/target/somefile1.txt not a dir
/home/otherdir/target/somefile2.txt not a dir
/home/otherdir/target/somefile3.txt a dir
/home/otherdir/target/somefile4.txt a dir
Очевидно, я не должен получать разные ответы при запуске одного и того же сценария копирования/перемещения данных. Примечательно, однако, что файлы берутся из одной директории (не могу понять, из какой они все одинаковые по содержанию), а остальные директории сохраняются. Таким образом, при каждом запуске для одного $sub_dir сценарий копировал содержимое каталога в место назначения, а не сам каталог. Это означает, что я теряю каталог при каждом запуске скрипта... Хотя я не понимаю, почему.
Я думаю, что я неправильно использую dircopy
и dirmove
, и я также не уверен, что $File::Copy::Recursive::CPRFComp = 1;
верен (я не нашел документацию очень понятной для моих новичков). есть идеи?
После еще нескольких копаний я думаю, что это то, что происходит. Небольшая документация по CPRFComp читает (при условии, что «foo/file»):
dircopy('foo', 'bar') or die $!;
# if bar does not exist the result is bar/file
# if bar does exist the result is bar/file
$File::Copy::Recursive::CPRFComp = 1;
dircopy('foo', 'bar') or die $!;
# if bar does not exist the result is bar/file
# if bar does exist the result is bar/foo/file
Таким образом, я предполагаю, что первое действие копирования/перемещения подкаталога запускается до того, как существует целевое местоположение («bar» в примере), что приводит к bar/file, а не bar/foo/file. Затем вопрос меняется на: как я могу убедиться, что мои операции копирования/перемещения ждут, пока целевой каталог не будет построен?
$source_location/$sub_dir did not match regex
, но ваше сообщение об ошибке показывает. did not match regex
без косой черты. Таким образом, вы либо не показываете свой реальный код, либо не показываете свой реальный результат. Пожалуйста, покажите ваш фактический код и ваше фактическое сообщение об ошибке, иначе мы не сможем узнать, являются ли обнаруженные нами проблемы вашими реальными проблемами или просто результатом ошибочной публикации вашей проблемы. - person Paul L   schedule 10.10.2016