#windows #perl #path #case-sensitive #cwd
#Windows #perl #путь #чувствителен к регистру #cwd
Вопрос:
Рассмотрим следующий код:
print cwd . "n";
$str= "../source"; # note the lower case 's'
chdir($str);
print cwd . "n";
Если мой текущий каталог c:parentdirSource
(обратите внимание на заглавные буквы), результат этого будет:
c:/parentdir/Source c:/parentdir/source
Это вызывает проблемы в моей подпрограмме, которая заботится о правильном регистре имен папок. $ str передается в мою подпрограмму, поэтому я не могу заранее знать, имеет ли он правильный регистр. Как мне определить правильное по регистру имя соответствующего пути $str
?
Подробнее здесь:
- Я понимаю, что
../source
это патологический пример, но он служит иллюстрацией проблемы. Это происходит, даже если$str
запрашивается папка, отличная от текущей. - Я пробовал множество вариантов,
rel2abs
в том числе поиск по$str
глобусу и другие, но все они, похоже, возвращают «source
» вместо «Source
«. - Я мог бы выполнить поиск
$str/..
по всем каталогам, преобразовать их все в абсолютные пути и сравнить их с версией абсолютного пути$str
, но это похоже на взлом. Я надеялся на что-то более элегантное.
Комментарии:
1. Это не неверно. Обычно файловые системы Windows не зависят от регистра, если NTFS не настроена иначе.
2. Абсолютно верно. К сожалению, моей подпрограмме нужен правильный регистр по причинам, отличным от простого манипулирования файловой системой. Итак, хотя Windows и Perl не заботятся, мне, к сожалению, приходится.
3. Да, без учета регистра, но он также сохраняет регистр . Если файл создан как
Foo
, к нему можно получить доступ с помощьюfoo
, но система знает, что его имяFoo
.
Ответ №1:
#!/usr/bin/perl
use warnings; use strict;
use Cwd;
use File::Spec::Functions qw( canonpath );
use Win32;
print canonpath( cwd ), "n";
chdir '../source';
print canonpath( cwd ), "n";
print canonpath( Win32::GetLongPathName( cwd ) ), "n";
C:DOCUME ~1...LOCALS ~ 1Temp tSource> t C:DOCUME ~1...LOCALS ~ 1Temp t Source C:DOCUME ~1...LOCALS ~ 1Temp t source C:Documents и Настройки...Local Settings Temp t Source
Комментарии:
1. Спасибо! Мне кажется, что мне даже не нужен canonpath. Если я выдам следующее: $str = Win32::GetLongPathName($str); , то, похоже, он изменится на правильный регистр, даже если $ str указывает относительный путь.
2.
canonpath
это просто получить косые черты в стиле Windows в путях, если это имело значение.
Ответ №2:
Я использую cygwin и svn, и я нашел этот вопрос, когда svn не смог найти эти файлы, потому что он учитывал регистр
например, $ cd /cygdrive /c / svn / delphi2010 /lib / контрольная сумма # неверный регистр
$ svn ls svn: предупреждение: W155010: узел ‘/cygdrive/c/svn / delphi2010 /lib / контрольная сумма’ не найден. svn: E200009: не удалось перечислить все цели, потому что некоторые цели не существуют
$ eval cd $( cygpath $( perl -le ‘использовать Win32; $ d= cygpath -aw .
; chomp($d); распечатать Win32::GetLongPathName($ d)’ ) )
$ pwd /cygdrive/c /svn/ Delphi2010/lib / Контрольная сумма # обратите внимание, что регистр восстановлен