Perl: проверить, является ли строка допустимым каталогом, регистр SENSITIVE
Итак, я столкнулся с проблемой. Ключ -d проверит, существует ли каталог просто отлично. Тем не менее, мне нужно, чтобы он был чувствительным к регистру. Если у меня есть каталог Users, и я делаю, если -d "UsErS", он вернет true. Мне нужно, чтобы он возвращал истину только в случае совпадения.
Буду признателен за любую оказанную помощь.
Код:
if (-d $cmdLine[1]) {
chdir $cmdLine[1];
print "CD: Successfully changed directory.\n";
} else {
print "CD: Error: $cmdLine[1] is not a valid directory.\n";
}
3 ответа
Единственным определенным источником для имени файла является сама файловая система. Этот фрагмент содержит список записей в родительском каталоге назначения и проверяет, что указанное имя точно совпадает с одной из этих записей. Я тестировал Linux с удаленного общего ресурса NTFS (смонтированного с CIFS).
use File::Basename;
$target = shift;
($base,$parent) = fileparse($target);
opendir($PARENT,$parent)
or die("Error opening '$parent': $!");
%entries = map { $_ => 1 } readdir($PARENT);
closedir($PARENT);
if (-d $target && exists($entries{$base})) {
print("'$target' exists (and correct case)\n");
} else {
print("'$target' does not exist.\n");
}
Я не могу представить, как вы могли бы столкнуться с этой проблемой вне файловой системы, не чувствительной к регистру (например, NTFS, (V)FAT, другие?), И проблема с ними (по крайней мере, когда Windows управляет ОС) заключается в том, что Вы не можете обязательно гарантировать, что регистр записи в файловой системе соответствует желаемому. Например, попробуйте переименовать файл NTFS, изменив только регистр. В Windows имя файла не меняется. Вы должны полностью изменить его на что-то другое, а затем заменить его на старое имя с правильным регистром. Существуют (или были) настраиваемые параметры Windows, которые делают особые вещи, если имя файла все в верхнем регистре.
Еще одна вещь, которую следует учитывать, это то, что если файловая система нечувствительна к регистру, то нет никакой возможности, что в одном каталоге могут быть две записи, которые отличаются только регистром. Я просто не понимаю, какую полезную непредвиденную ситуацию может принести эта проверка.
Проверьте Win32
модуль,
use Win32;
if (-d $cmdLine[1] and $cmdLine[1] eq Win32::GetLongPathName($cmdLine[1])) { .. }
Вам также может понадобиться use File::Spec::Functions 'canonpath';
если вы хотите нормализовать разделители каталогов (/
в \
на win32)
TLP предлагает объединить оба -d
а также eq
, Что-то вроде:
if (-d $dirname && $dirname eq "Users"){
....
}
КСТАТИ -d
один работает нормально для меня. Это чувствительно к регистру. Попробуйте приведенный ниже код и измените $dir на любой каталог, который существует в вашей системе.
#!/usr/bin/perl
use strict;
use warnings;
my $dir = "/pathto/code";
if(-d $dir){print "DIR: $dir";}
else{print "$dir is not a directory";}