为什么Windows上的cmd.exe shell使用正斜杠('/'')路径分隔符失败?

Gar*_*ren 16 windows cmd spaces path path-separator

就在我以为我已经看到了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.
Run Code Online (Sandbox Code Playgroud)

特别有趣的是它似乎是特定于cmd.exe shell而不是在PowerShell中出现(也不是在win32 API中):

PS C:\temp\tcbugs> type 'dir1 with spaces/foo.txt'
hi
Run Code Online (Sandbox Code Playgroud)

另一个兴趣点是使用'cd'更改目录并使用'/'作为cmd.exe的路径分隔符确实有效:

C:\temp\tcbugs>mkdir dir2_no_spaces

C:\temp\tcbugs>cd ./dir2_no_spaces

C:\temp\tcbugs\dir2_no_spaces>cd ..
Run Code Online (Sandbox Code Playgroud)

然而,我无法在网上或MSDN的常用文档中找到任何对此特定问题的引用:

命名文件,路径,命名空间

这引出了我的问题:为什么会发生这种情况,是否有一个明确的来源记录了这个怪癖?

更新:

dbenham指出,无论空格是否在目录名称中,问题都存在,因此在标题和问题正文中删除了对它的引用.还添加了一个有效的"cd ./"示例,而其他命令则没有.

dbe*_*ham 9

编辑删除意见

无论Windows CMD.EXE是否应该支持路径中的正斜杠,事实上它有时会起作用,有时它不起作用,有时它似乎工作但却给出了错误的结果 - AKA是一个错误.

这是一些实验的时间:-)

所有测试都在Vista上运行

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
Run Code Online (Sandbox Code Playgroud)

这是一个清楚地演示错误的案例.

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!
Run Code Online (Sandbox Code Playgroud)

人们可以争论Windows CMD是否"应该"支持正斜杠.但最后的结果是一个错误!即使使用正斜杠存在操作员错误,Windows也不应该提供该结果.

  • @BrianNixon - 如果系统给出不一致的结果,我认为这是一个错误(或设计缺陷).如果CMD在路径中使用正斜杠或者没有工作,我会非常高兴,但有时工作和其他时间不是我书中的错误.我在编辑的答案中的最后一个例子清楚地表明了我能想到的任何理由定义的"bug"的错误.我已经从答案中删除了意见并坚持了事实.但在这篇评论中,我将说:"我相信MS试图在路径中支持正斜线,最终得到了一个有缺陷的无证功能". (6认同)
  • 将行为描述为错误的基础是什么?(正如上面提到的Raymond Chen所说的那样,文档中指出`cmd`应该接受正斜杠作为路径分隔符?)和Larry Osterman [注意到](http://blogs.msdn.com/b/larryosterman/archive/2005 /06/24/432386.aspx),使用正斜杠作为选项分隔符的起源可能甚至不是微软的做法.您是否会将Unix传统命令的行为描述为"错误",这些命令无法处理以`-`开头而没有特殊排列的文件名? (3认同)
  • @dbenham:我几乎可以肯定 MS 没有尝试在 `cmd` 中支持正斜杠。他们(有意地)在 API 中支持它们,但在 `cmd` 中,它恰好在文本刚刚传递给 API 时起作用,而不是在解析时起作用。`md` 和 `type` 之间的区别,都是内置命令,真的很好奇。 (2认同)

Dav*_*.ca -7

我不确定为什么“/”在 PS 中起作用。回到历史,DOS 是基于 UNIX 的,它是 UNIX 的一个小集合。在 UNIX 中,路径分隔符是“/”,而在 DOS 中,路径分隔符是“\”。我之前曾开发过一些 Windows 和 DOS 应用程序。为了转换一些 UNIX 模式(如命令或路径)并确保它们是有效的 DOS 命令或路径,我编写了一个小型转换器来将 '/' 转换为 '\',如下所示:

string fileNameFromWeb;
...
string windowsFile = fileNameFromWeb.repleace("/", @"\");
Run Code Online (Sandbox Code Playgroud)

您可以将此功能添加到应用程序中的宽容“/”中,以便访问 Windows 中的文件。我猜 PS 可能有这种类型转换器,允许命令或路径使用“/”或“\”,否则 Windows 将在文件名中采用“/”。

  • -1 抱歉,“DOS 是基于 UNIX 的,而且它是 UNIX 的一小部分。”,这是有史以来最大的亵渎!实际上,DOS 在某种程度上是基于 CP/M 的。 (8认同)