为什么Windows上的cmd.exeshell失败,path使用正斜杠('/'')path分隔符?

就在我以为我已经看到所有的Windowspath问题,我现在遇到了一个情况,只有当使用“/”(正斜杠)作为使用的path分隔符时失败:

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.exeshell,并不会在PowerShell(也可能在win32 API)中出现:

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

还有一点值得注意的是,使用'cd'改变目录并使用'/'作为cmd.exe的path分隔符是行不通的:

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

然而,我无法在网上或MSDN的常用文档中find任何有关此特定问题的提及:

命名文件,path,命名空间

这导致我问:为什么会发生这种情况,是否有一个明确的来源来logging这个怪癖?

更新:

dbenham指出,无论空格是否在目录名称中,都存在问题,因此在标题和问题主体中删除了引用。 还添加了一个“cd ./”的例子,而其他命令则不行。

编辑删除意见

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

是时候进行一些实验了:-)

所有的测试都在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 

这是一个清楚地显示错误的例子。

 c:\>dir /s /ad 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 listd: 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也不应该给出结果。

魏有一些奇怪的行为,我们追溯到这样一个事实,那就是一条带有斜线的路径并不是绝对的路径,所以

 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 

也许这也解释了上面提到的错误 – 我不清楚,命令在哪个目录下执行。

我不知道为什么'/'在PS中工作。 回到历史,DOS是基于UNIX,它是一小部分的UNIX。 在UNIX中,路径分隔符是'/',而在DOS中是'\'。 我曾经在一些Windows和DOS应用程序上工作过。 为了转换一些UNIX模式,如命令或路径,并确保它们是有效的DOS命令或路径,我写了一个小型转换器将“/”转换为“\”,如下所示:

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

在Windows中访问文件的情况下,您可以在您的应用中添加此功能以容忍“/”。 我猜PS可能有这种类型的转换器,允许命令或路径使用'/'或'\',或Windows将采取'/'的文件名。