2014-12-30 2 views
2

Так что у меня возникла проблема. Переключатель -d проверяет, существует ли только каталог. Однако мне нужно, чтобы это было чувствительным к регистру. Если у меня есть каталог Users, и я делаю, если -d "UsErS", он вернет true. Мне нужно, чтобы он возвращал true только в случае совпадения.Perl: Проверьте, является ли строка действительной директорией, case SENSITIVE

Любая помощь очень ценится.

Код:

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"; 
} 
+0

Есть ли какой-либо причине вы не можете комбинировать '-d' с' eq'? – TLP

+0

@TLP Что значит? Как именно вы это сделаете? – RogueCSDev

+0

'-d' будет чувствителен к регистру как файловая система, поэтому, если файловая система не является файловой системой NTFS или (V) FAT, она, скорее всего, будет вести себя так, как вы хотите. – mojo

ответ

5

Единственным определяющим источником для имени файла является сама файловая система. В этом фрагменте перечислены записи в родительском каталоге целевого каталога и проверяется, что указанное имя точно совпадает с одной из этих записей. Я тестировал 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, является OS, управляющая им) заключается в том, что вы не можете гарантировать, что случай ввода файловой системы - это то, что вы хотите. Например, попробуйте переименовать файл NTFS, изменяя только случай. В Windows имя файла не изменяется. Вам нужно будет полностью изменить его на что-то другое, а затем изменить его на прежнее имя с правильным случаем. Существуют (или были) настраиваемые параметры Windows, которые делают специальные вещи, если имя файла имеет верхний регистр.

Еще одна вещь, которую следует учитывать, заключается в том, что если файловая система не чувствительна к регистру, то нет никакой возможности, что в одном каталоге могут быть две записи, которые отличаются только по отдельности. Я просто не понимаю, какая полезная непредвиденная ситуация для этой проверки.

0

Что TLP предлагает, чтобы объединить оба -d и eq. Что-то вроде:

if (-d $dirname && $dirname eq "Users"){ 
.... 
} 

BTW -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";} 
+0

Но дело в том, что я не уверен, каким будет имя каталога. Это могут быть пользователи или сервер или что угодно. – RogueCSDev

+0

Не могли бы вы поделиться своим кодом, потому что '-d' чувствителен к регистру, я проверил. –

+0

Добавлен соответствующий код. – RogueCSDev

2

Проверить Win32 модуль,

use Win32; 

if (-d $cmdLine[1] and $cmdLine[1] eq Win32::GetLongPathName($cmdLine[1])) { .. } 

Вам также может понадобиться use File::Spec::Functions 'canonpath';, если вы хотите, чтобы нормализовать разделители каталогов (/ в \ на win32)