Используя Perl в Windows, как я могу убедиться, что в правильном случае я получаю путь, следующий за chdir?

Рассмотрим следующий код:

print cwd . "\n";
$str= "../source"; # note the lower case 's'    
chdir($str);
print cwd . "\n";

Если мой текущий каталог c:\parentdir\Source (обратите внимание на заглавную букву 'S'), результат этого будет:

C:/parentdir/ Источник
C:/parentdir/ источник

Это вызывает проблемы в моей подпрограмме, которая заботится о правильном регистре имен папок. $str передается в мою подпрограмму, поэтому я не могу заранее знать, имеет ли она правильный регистр. Как определить правильное для регистра имя пути, соответствующего $str?

Более подробно здесь:

  • Я понимаю что ../source Это патологический пример, но он служит для иллюстрации проблемы. Это происходит, даже если $str запрашивает папку, отличную от текущей.
  • Я перепробовал множество вариантов, в том числе rel2absПоиск по$strи другие, но все они, кажется, возвращаютсяsource" вместо "Source".
  • Я мог бы искать $str/.. для всех каталогов преобразуйте их в абсолютные пути и сравните с версией абсолютного пути $str, но это похоже на взломать. Я надеялся на что-то более элегантное.

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~1\Temp\t\Source> t
C:\DOCUME~1\...\LOCALS~1\Temp\ т \Source
C:\DOCUME~1\...\LOCALS~1\Temp\ т \ источник
C:\Documents and Settings\...\ Локальные настройки \ Temp \ t \ Source

Я использую 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 .; чавкать ($d); печать Win32::GetLongPathName($d)'))

$ pwd / cygdrive / c / svn / Delphi2010 / lib / CheckSum # обратите внимание, что случай восстановлен

и svn ls снова работает!

Другие вопросы по тегам