问题
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:
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):
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:
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:
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. Also added an example of 'cd ./' that works, while other commands don't.
回答1:
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.
It's time for some experiments :-)
All tests were run on 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. But that last result is a bug! Even if there is operator error in using a forward slash, Windows should not give that result.
回答2:
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
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.
回答3:
I am not sure why the '/' is working in PS. Back to the history, DOS was based on UNIX and it is a small set of UNIX. In UNIX the path separator is '/', while in DOS it is '\'. I worked on some Windows and DOS apps before. 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:
string fileNameFromWeb;
...
string windowsFile = fileNameFromWeb.repleace("/", @"\");
You may add this feature to tolerant '/' in your app in case of accessing to files in Windows. I guess PS may have this type converter to allow command or path using '/' or '\', or Windows will take '/' in file name.
来源:https://stackoverflow.com/questions/10523708/why-does-the-cmd-exe-shell-on-windows-fail-with-paths-using-a-forward-slash