2012-05-09 4 views
12

Как раз тогда, когда я думал, что видел все это с проблемами пути к Windows, я столкнулся с ситуацией, которая не срабатывает, когда используется '/' (forward-slash), когда используется разделитель путей:Почему оболочка cmd.exe на Windows работает с путями с использованием разделителя пути вперед-вниз ('/' ')?

C:\temp\tcbugs>mkdir "dir1 with spaces" 

C:\temp\tcbugs>echo hi > "dir1 with spaces"\foo.txt 

C:\temp\tcbugs>type "dir1 with spaces\foo.txt" 
hi 

C:\temp\tcbugs>type "dir1 with spaces/foo.txt" 
The system cannot find the file specified. 

что особенно интересно о том, что это, как представляется, характерные для cmd.exe оболочки и не происходит в PowerShell (ни предположительно в win32 API):

PS C:\temp\tcbugs> type 'dir1 with spaces/foo.txt' 
hi 

Еще один интересный заключается в том, что смена директорий с 'cd' и использование '/', используемого в качестве разделителя путей с cmd.exe, работает:

C:\temp\tcbugs>mkdir dir2_no_spaces 

C:\temp\tcbugs>cd ./dir2_no_spaces 

C:\temp\tcbugs\dir2_no_spaces>cd .. 

Тем не менее, я не могу найти никаких ссылок на эту конкретную проблему где-нибудь в Интернете, ни в широко цитируемой документации MSDN по:

Naming Files, Paths, Namespaces

Который ведет меня спросить: почему это происходит, и является есть ли окончательный источник, который документирует эту причуду?

UPDATE:

dbenham указывает на то, что проблема присутствует независимо от того, являются ли пробелы в имени каталога, поэтому удалена ссылка на него в названии и расспросить тело. Также добавлен пример «cd ./», который работает, а другие - нет.

+5

'/' может использоваться как разделитель путей на уровне API, но вы не вызываете API напрямую. Вы используете cmd.exe, а cmd.exe анализирует параметр '/' как параметр командной строки. –

+0

Я подозревал столько же, но и ожидал, что что-то, покрывающее этот случай, будет где-то зарегистрировано. Документация, которую я нашел, охватывает разделители путей - даже в контексте оболочки cmd - не упоминает эту конкретную проблему, насколько я могу судить. – Garen

+1

Где документация, которая говорит, что косая черта может использоваться в качестве разделителя путей в cmd.exe? –

ответ

-6

Я не уверен, почему '/' работает в PS. Вернемся к истории, DOS была основана на UNIX, и это небольшой набор UNIX. В UNIX разделитель путей имеет значение «/», а в DOS - «\». Раньше я работал над некоторыми приложениями Windows и DOS. Для того, чтобы преобразовать некоторый UNIX шаблон, как команда или путь и убедиться, что они являются действительной командой DOS или путем, я написал небольшой конвертер для преобразования «/» до «\», как это:

string fileNameFromWeb; 
... 
string windowsFile = fileNameFromWeb.repleace("/", @"\"); 

Вы можете добавить это для толерантного «/» в вашем приложении в случае доступа к файлам в Windows. Я думаю, PS может иметь этот тип конвертер, чтобы разрешить команду или путь, используя '/' или '\', или Windows примет '/' в имени файла.

+0

Спасибо, но то, что изначально привело меня к этой проблеме, было ошибкой в ​​некоторых сторонних программах - так что опция недоступна мне. Конечно, если бы это было мое программное обеспечение, я бы просто сделал что-то подобное и не потрудился задавать этот вопрос. – Garen

+0

Если вы используете .NET или Mono, вы можете использовать Path.DirectorySeparator вместо жесткого кодирования. http://msdn.microsoft.com/en-us/library/system.io.path.directoryseparatorchar.aspx – dwerner

+6

-1 Извините, но «DOS был основан на UNIX, и это небольшой набор UNIX.», который имеет стал самым большим богохульством! Фактически, DOS была несколько [основана] (http://en.wikipedia.org/wiki/DOS#Origins) на CP/M. –

8

Edited удалить мнение

ли не для Windows CMD.EXE должен поддерживать прямую косую черту в пути, то иногда это работает, иногда нет, а иногда кажется, работает, но дает неправильный результат - AKA - ошибка.

Это время для некоторых экспериментов :-)

Все тесты проводились на Висте

C:\>md "c:/temp/" 

C:\>REM The forward slash works with MD! 

C:\>echo hello world 1>>"c:/temp/test.txt" 

C:\>REM Redirection works with forward slashes! 

C:\>type "c:\temp\test.txt" 
hello world 

C:\>REM Of course TYPE works with back slashes 

C:\>type "c:/temp/test.txt" 
The system cannot find the file specified. 

C:\>REM But forward slash version fails 

C:\>type "c:/temp\test.txt" 
hello world 

C:\>REM But TYPE works with forward slash as long as last slash is back slash 

C:\>dir "c:/temp/test.txt" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp 

File Not Found 

C:\>REM Note how DIR lists the directory with a \, yet fails to find any files 

C:\>dir "c:/temp/*" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp 

File Not Found 

C:\>REM DIR Still fails with forward slashes 

C:\>dir "c:/temp/" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp 

05/09/2012 09:58 PM <DIR>   . 
05/09/2012 09:58 PM <DIR>   .. 
05/09/2012 09:58 PM    13 test.txt 
       1 File(s)    13 bytes 
       2 Dir(s) 337,001,615,360 bytes free 

C:\>REM But forward slash works if no file is specified! 

C:\>dir "c:/temp\test.txt" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp 

05/09/2012 09:58 PM    13 test.txt 
       1 File(s)    13 bytes 
       0 Dir(s) 337,001,615,360 bytes free 

C:\>REM And DIR works with forward slash as long as last slash is back slash 


C:\>REM Now add another folder to the path hierarchy 

C:\>md "c:/temp/temp/" 

C:\>REM Still can create folder using forward slashes 

C:\>copy "c:/temp/test.txt" "c:/temp/temp/" 
The system cannot find the file specified. 
     0 file(s) copied. 

C:\>REM Failed to copy with forward slashes 

C:\>copy "c:/temp\test.txt" "c:/temp/temp/" 
     1 file(s) copied. 

C:\>REM But forward slash works if last slash before file name is back slash 


C:\>REM Rerun some past tests 

C:\>type "c:/temp/test.txt" 
The system cannot find the file specified. 

C:\>REM Good - it still fails 

C:\>dir "c:/temp/test.txt" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp 

05/09/2012 09:58 PM    13 test.txt 
       1 File(s)    13 bytes 
       0 Dir(s) 337,001,615,360 bytes free 

C:\>REM What is going on?! :(Why did that seem to work now? 
C:\>REM More on that later. 


C:\>REM Now test the new folder 

C:\>type "c:/temp/temp/test.txt" 
The system cannot find the file specified. 

C:\>REM Forward slashes still fail with TYPE 

C:\>type "c:/temp/temp\test.txt" 
hello world 

C:\>REM But forward slash still works as long as last slash is back slash 

C:\>dir "c:/temp/temp/*" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp\temp 

File Not Found 

C:\>REM Again, forward slashes fail, but directory path is listed properly 

C:\>dir "c:/temp/temp/" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp\temp 

05/09/2012 09:58 PM <DIR>   . 
05/09/2012 09:58 PM <DIR>   .. 
05/09/2012 09:58 PM    13 test.txt 
       1 File(s)    13 bytes 
       2 Dir(s) 337,001,615,360 bytes free 

C:\>REM And again it works if no file is specified 

C:\>dir "c:/temp/temp\test.txt" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp\temp 

05/09/2012 09:58 PM    13 test.txt 
       1 File(s)    13 bytes 
       0 Dir(s) 337,001,615,360 bytes free 

C:\>REM Again forward slashes work as long as last slash is back slash 

Вот случай, который ясно показывает ошибку.

c:\>dir /s /a-d temp 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp 

05/10/2012 08:01 AM    13 test.txt 
       1 File(s)    13 bytes 

Directory of c:\temp\temp 

05/10/2012 07:57 AM    10 test.txt 
       1 File(s)    10 bytes 

    Total Files Listed: 
       2 File(s)    23 bytes 
       0 Dir(s) 337,325,191,168 bytes free 

c:\>REM Note the different file sizes found in each directory 

c:\>dir "c:/temp/test.txt" 
Volume in drive C is OS 
Volume Serial Number is EE2C-5A11 

Directory of c:\temp 

05/10/2012 07:57 AM    10 test.txt 
       1 File(s)    10 bytes 
       0 Dir(s) 337,325,191,168 bytes free 

c:\>REM It is listing the wrong file! 

Можно обсуждать, поддерживает ли Windows CMD поддержку передних косых черт. Но этот последний результат - ошибка! Даже если есть ошибка оператора при использовании косой черты, Windows не должна давать такой результат.

+0

+1 для интересного эксперимента! –

+3

Какова ваша основа для описания поведения в качестве ошибки? (Как сказал Раймонд Чен выше, где документация, в которой говорится, что 'cmd' должен принимать косые черты в качестве разделителей путей?) И как Ларри Остерман [отмечен] (http://blogs.msdn.com/b/larryosterman/archive/2005 /06/24/432386.aspx), происхождение использования косой черты в качестве разделителя параметров, возможно, даже не делает Microsoft. Вы описали бы как «ошибку» поведение команд Unix-традиции, которые не могут иметь дело с именами файлов, начинающимися с '-' без специальной договоренности? –

+6

@BrianNixon - я считаю это ошибкой (или дефектом дизайна), если система дает непоследовательные результаты.Я был бы совершенно счастлив, если бы CMD работал с косой чертой в пути или не делал этого, но иногда работать, а иногда и не был ошибкой в ​​моей книге. И мой последний пример в отредактированном ответе наглядно демонстрирует ошибку с помощью любого рационального определения «ошибки», о котором я могу думать. Я удалил мнение из ответа и придерживался фактов. Но в этом комментарии я укажу: «Я считаю, что MS пыталась поддерживать косые черты в путях и заканчивала работу с недопустимой недокументированной функцией». – dbenham

-1

Wie было какое-то странное поведение с косой черты к и мы прослеживали его сводится к тому, что путь с слэш не рассматривается как абсолютный путь, так

C:\>cd /temp 

C:\temp>rem works we are in the root directory 

C:\temp>cd /temp 
Das System kann den angegebenen Pfad nicht finden. 

C:\temp>rem does't work but 

C:\temp>cd \temp 

C:\temp>rem \ indicates absolute path 

C:\temp>cd .. 

C:\>cd /temp 

C:\temp> cd /ca 

C:\temp\CA>rem qed 

Возможно, это объясняет также ошибка, указанная выше - im непонятно, в каком каталоге выполняются команды.

+0

Хорошая теория, но на моей машине с Windows 7 у меня другое поведение. 'cd/temp' отлично работает для меня, рассматривая его как корневую папку. Но другие ошибки, которые я перечисляю в моем сообщении, все еще применяются. – dbenham

+0

Это интересные примеры, но они даже не начинают рассматривать вопрос «почему». –