简体   繁体   English

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

[英]Why does the cmd.exe shell on Windows fail with paths using a forward-slash ('/'') path separator?

Just when I'd thought I'd seen it all with Windows path issues, I've now encountered a case that only fails when '/' (forward-slash) is used as the path separator is used: 就在我以为我已经看到了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.

What is particularly interesting about this is that it appears to be specific to the cmd.exe shell and doesn't occur in PowerShell (nor presumably in the win32 API): 特别有趣的是它似乎是特定于cmd.exe shell而不是在PowerShell中出现(也不是在win32 API中):

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

Another point of interest is that changing directories with 'cd' and using '/' used as a path separator with cmd.exe does work: 另一个兴趣点是使用'cd'更改目录并使用'/'作为cmd.exe的路径分隔符确实有效:

C:\temp\tcbugs>mkdir dir2_no_spaces

C:\temp\tcbugs>cd ./dir2_no_spaces

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

Yet, I can't find any reference to this particular problem anywhere online nor in MSDN's commonly cited documentation: 然而,我无法在网上或MSDN的常用文档中找到任何对此特定问题的引用:

Naming Files, Paths, Namespaces 命名文件,路径,命名空间

Which leads me to ask: why does this happen, and is there a definitive source which documents this quirk? 这引出了我的问题:为什么会发生这种情况,是否有一个明确的来源记录了这个怪癖?

UPDATE: 更新:

dbenham points out that the problem is present regardless of whether spaces are in a directory name, so removed reference to it in the title and question body. dbenham指出,无论空格是否在目录名称中,问题都存在,因此在标题和问题正文中删除了对它的引用。 Also added an example of 'cd ./' that works, while other commands don't. 还添加了一个有效的“cd ./”示例,而其他命令则没有。

Edited to remove opinion 编辑删除意见

Whether or not Windows CMD.EXE is supposed to support forward slashes in paths, the fact is sometimes it works, sometimes it doesn't, and sometimes it appears to work but gives the wrong result - AKA a bug. 无论Windows CMD.EXE是否应该支持路径中的正斜杠,事实上它有时会起作用,有时它不起作用,有时它似乎工作但却给出了错误的结果 - AKA是一个错误。

It's time for some experiments :-) 这是一些实验的时间:-)

All tests were run on Vista 所有测试都在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

Here is a case that clearly demonstrates a bug. 这是一个清楚地演示错误的案例。

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!

One can debate whether Windows CMD is "supposed" to support forward slashes. 人们可以争论Windows CMD是否“应该”支持正斜杠。 But that last result is a bug! 但最后的结果是一个错误! Even if there is operator error in using a forward slash, Windows should not give that result. 即使使用正斜杠存在操作员错误,Windows也不应该提供该结果。

Wie had some strange behaviour with slash to and we traced it down to the fact, that a path with a leading slash isn't seen as an absolute path, so 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

Perhaps it explains also the bug stated above - im not clear, at which directory the commands are executed. 也许它也解释了上面提到的错误 - 我不清楚,在哪个目录下执行命令。

I am not sure why the '/' is working in PS. 我不确定为什么'/'在PS中有效。 Back to the history, DOS was based on UNIX and it is a small set of UNIX. 回到历史,DOS基于UNIX,它是一小部分UNIX。 In UNIX the path separator is '/', while in DOS it is '\\'. 在UNIX中,路径分隔符是'/',而在DOS中它是'\\'。 I worked on some Windows and DOS apps before. 之前我曾在一些Windows和DOS应用程序上工作。 In order to convert some UNIX pattern like commands or path and make sure they are valid DOS command or path, I wrote a small converter to transform '/' to '\\' like this: 为了转换一些UNIX模式,如命令或路径,并确保它们是有效的DOS命令或路径,我写了一个小转换器,将'/'转换为'\\',如下所示:

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

You may add this feature to tolerant '/' in your app in case of accessing to files in Windows. 如果访问Windows中的文件,您可以在应用程序中将此功能添加到容忍'/'。 I guess PS may have this type converter to allow command or path using '/' or '\\', or Windows will take '/' in file name. 我想PS可能有这种类型转换器允许命令或路径使用'/'或'\\',或Windows将在文件名中取'/'。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM