22

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.

Garen
  • 941
  • 2
  • 9
  • 20
  • 9
    `/` can be used as a path separator at the API level, but you aren't calling the API directly. You're using cmd.exe, and cmd.exe parses the `/` as a command line option. – Raymond Chen May 09 '12 at 20:49
  • I suspected as much, but also expected something covering this case would be documented somewhere specifically. The documentation I have found covering path separators--even in the context of the cmd shell--doesn't mention this particular issue so far as I can tell. – Garen May 09 '12 at 20:52
  • 1
    Where is the documentation that says slash can be used as a path separator in cmd.exe? – Raymond Chen May 09 '12 at 22:26
  • The spaces have nothing to do with the problem. Even if the folder does not have spaces in the name, the forward slash still does not work. – dbenham May 09 '12 at 22:47
  • Raymond--Looking just now, I don't actually see anything mentioned cmd.exe explicitly. – Garen May 09 '12 at 23:31
  • dbenham--Looks like I'm mistaken about the spaces having anything to do with the problem; will edit the question. – Garen May 09 '12 at 23:32
  • If you have a top-level directory named 'D', `cd /D` won’t work... – Brian Nixon May 09 '12 at 23:57
  • @BrianNixon: Seems like `CD` works inconsistently with `/`-delimited paths. If the path *starts* with a `/`, `CD` will say it can't find it (unless you are trying `/D`, in which case it will complain about the syntax error). – Andriy M May 10 '12 at 01:48
  • @AndriyM - `CD /TEMP` works for me on Vista. `CD /D` does nothing because of the /D option. Nor does `CD "/D"` work. But `CD C:/D` works just fine! – dbenham May 10 '12 at 02:23
  • @dbenham: Thanks. That's "testing when sleepy" for you: for some reason it didn't occur to me to try a name that didn't begin with `d`. I was using `dd` in my tests, and I was on XP SP3 at the time, by the way. Now I am on Win7 and I can confirm two things: `CD /Temp` does work and `CD /Danything` doesn't seem to. So, thanks again, for reminding me what sensible people are supposed to do anight. :) – Andriy M May 10 '12 at 04:55
  • Also note that the `type` in `CMD.EXE` and `type` in PowerShell are not the same command (like some external `type.exe`). In `CMD.EXE` it is built-in and in PowerShell it is the `Get-Content` commandlet. `CMD.EXE` built-ins parse their arguments sometimes different than external commands do (for example `cd..` is the same as `cd ..`). – Christian.K May 10 '12 at 05:29
  • http://webpages.charter.net/danrollins/techhelp/0295.HTM – Cheers and hth. - Alf Feb 24 '13 at 22:10

3 Answers3

10

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.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • 3
    What’s your basis for describing the behaviour as a bug? (As Raymond Chen asked above, where’s the documentation that states that `cmd` should accept forward slashes as path separators?) And as Larry Osterman [noted](http://blogs.msdn.com/b/larryosterman/archive/2005/06/24/432386.aspx), the origin of the use of the forward slash as the option separator might not even be Microsoft’s doing. Would you describe as a “bug” the behaviour of Unix-tradition commands that can’t deal with file names beginning with `-` without special arrangement? – Brian Nixon May 10 '12 at 08:26
  • 8
    @BrianNixon - I consider it a bug (or design flaw) if a system gives inconsistent results. I'd be perfectly happy if CMD worked with forward slash in paths or didn't, but to sometimes work and other times not is a bug in my book. And my last example in the edited answer clearly demonstrates a bug by any rational definition of "bug" that I can think of. I've removed opinion from the answer and stuck to the facts. But in this comment I will state: "I believe MS attempted to support forward slashes in paths and ended up with a buggy undocumented feature". – dbenham May 10 '12 at 14:06
  • 2
    @dbenham: I am almost certain MS didn't attempt to support forward slashes in `cmd`. They (intentionally) support them in the API, but in `cmd` it just happens to work when the text is just passed to API and not when it is parsed. The difference between `md` and `type`, both being built-in commands, is really curious. – Jan Hudec Aug 27 '13 at 11:33
  • @JanHudec - I suppose the developers of `cmd` could have been naive as to the API's interpretation of `/`, but I doubt it. Either way, they *should* have been aware and designed accordingly. It should have been a conscious decision to either support `/` as a path separator in all internal command situations, or else disable it in all cases. That is my *opinion* anyway. :-) Or at least document that `/` is unreliable as a path separator and therefore should be avoided. – dbenham Aug 27 '13 at 13:01
  • @dbenham: It should have been documented. Perhaps it is, somewhere; Microsoft documentation is famous for being difficult to find what you are actually interested in. It couldn't have been supported, because `cmd.exe` is an NT port of `command.com` and I don't know whether forward slashes worked back then (DOS was not POSIX compliant, only WinNT and newer are). – Jan Hudec Aug 28 '13 at 06:47
-1

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.

  • Nice theory, but on my Windows 7 machine I get different behavior. `cd /temp` works fine for me, treating it as a root folder. But the other bugs I list in my post still apply. – dbenham Nov 02 '14 at 16:57
  • These are interesting examples, but they don't even begin to address the question of "why". – Bryan Oakley Nov 30 '16 at 22:37
-7

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.

David.Chu.ca
  • 37,408
  • 63
  • 148
  • 190
  • Thanks, but what originally led me to this problem was a bug in some third-party software--so that option isn't available to me. Of course, if it were my software I would have simply done something like that and not bothered to ask this question. – Garen May 09 '12 at 20:47
  • If you're using .NET or Mono, you can use Path.DirectorySeparator instead of hard-coding it. http://msdn.microsoft.com/en-us/library/system.io.path.directoryseparatorchar.aspx – dwerner May 10 '12 at 02:20
  • 8
    -1 Sorry, but "DOS was based on UNIX and it is a small set of UNIX.", that has got the be the biggest blasphemy ever! Actually, DOS was somewhat [based](http://en.wikipedia.org/wiki/DOS#Origins) on CP/M. – Christian.K May 10 '12 at 05:33
  • It works in PS, because it's parsing rules are different and when the string gets unmodified to the API, it works. – Jan Hudec Aug 27 '13 at 11:35
  • @dwerner: If you are using .NET or Mono, or C++ or anything, you can always use `/`. `cmd.exe` is the _only_ (or at least I've never header of any other) part of Windows where forward slashes don't work. – Jan Hudec Aug 27 '13 at 11:36
  • @JanHudec: There are, of course, quite a number of tools that allow a leading `/` to introduce command-line options. Thankfully for those of us using bash, *most* of these also allow `-`. (Whatever bash you might use on Windows, arguments starting with `/` will tend to be subject to path translation when invoking programs that it doesn't recognize as fellow *nix ex-pats, so it's generally a lot easier to just use `-` to introduce options than to fight the path translation.) Presumably you were only referring to non-leading `/`? – SamB May 26 '19 at 19:48