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

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

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:

Именование файлов, путей, пространств имен

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

UPDATE:

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

Ответ 1

Отредактировано для удаления мнения

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

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

Все тесты выполнялись в Vista​​p >

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 не должна давать такой результат.

Ответ 2

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

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 not clear, в каком каталоге выполняются команды.

Ответ 3

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

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

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