21

就在我以为我已经看到了 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.

对此特别有趣的是,它似乎特定于 cmd.exe shell,并且不会出现在 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 的常用文档中都找不到对这个特定问题的任何参考:

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

这让我不禁要问:为什么会发生这种情况,是否有确定的来源记录了这个怪癖?

更新:

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

4

3 回答 3

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

这是一个清楚地展示了一个错误的案例。

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 也不应该给出该结果。

于 2012-05-10T02:13:00.760 回答
-1

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

也许它也解释了上述错误 - 我不清楚命令在哪个目录执行。

于 2013-06-06T13:03:10.670 回答
-7

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

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

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

于 2012-05-09T20:45:02.173 回答