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";}
Другие вопросы по тегам