Strange Windows DIR command behavior

不羁岁月 提交于 2019-11-30 11:19:13

Wild cards at the command prompt are matched against both the long file name and the short "8.3" name if one is present. This can produce surprises.

To see the short names, use the /X option to the DIR command.

Note that this behavior is not in any way specific to the DIR command, and can lead to other (often unpleasant) surprises when a wild card matches more than expected on any command, such as DEL.

Unlike in *nix shells, replacement of a file pattern with the list of matching names is implemented within each command and not implemented by the shell itself. This can mean that different commands could implement different wild card pattern rules, but in practice this is quite rare as Windows provides API calls to search a directory for files that match a pattern and most programs use those calls in the obvious way. For programs written in C or C++ using the "usual" tools, that expansion is provided "for free" by the C runtime library, using the Windows API.

The Windows API in question is FindFirstFile() and its close relatives FindFirstFileEx(), FindNextFile(), and FindClose().

Oddly, although the documentation for FindFirstFile() describes its lpFileName parameter as "directory or path, and the file name, which can include wildcard characters, for example, an asterisk (*) or a question mark (?)" it never actually defines what the * and ? characters mean.

The exact meaning of the file pattern has history in the CP/M operating system dating from the early 1970s that strongly influenced (some might say "was directly copied" in place of "influenced" here) the design of MSDOS. This has resulted in a number of "interesting" artifacts and behaviors. Some of this at the DOS end of the spectrum is described at this blog post from 2007 where Raymond describes exactly how file patters were implemented in DOS.

Yep. You'll see that it also searches through short names if you try this:

dir /x *4*

(/x switch is for short names)

for filtering file names use :

dir /b | find "4"

A quote from RBerteig's answer:

Note that this behavior is not in any way specific to the DIR command, and can lead to other (often unpleasant) surprises when a wild card matches more than expected on any command, such as DEL.

The above is true even for the FOR command, which is very nasty.

for %A in (*4*) do @echo %A contains a 4

will also search the short names. The solution again would be to use FIND or FINDSTR to filter out the names in a more reliable manner.

for %A in (*) do @echo %A | >nul findstr 4 && echo %A contains a 4

Note - change %A to %%A if using the command within a batch file.

Combining FOR with FINDSTR can be a general purpose method to safely use any command that runs into problems with short file names. Simply replace ECHO with the problem command such as COPY or DEL.

Seems like dir command searches also short ( 8.3 manner ) file names under the hood.

When I call dir *1* this is what I get:

 Volume in drive C is System
 Volume Serial Number is F061-0B78

 Directory of C:\Users\Piotrek\Desktop\Downloads
2012-05-20  17:33        23 639 040 gDEBugger-5_8.msi
2012-05-20  17:30           761 942 glew-1.7.0.zip
2012-05-20  17:11         9 330 176 irfanview_plugins_433_setup.exe
2012-05-24  20:17         4 419 192 SumatraPDF-2.1.1-install.exe
2012-05-15  22:55         3 466 248 TrueCrypt Setup 7.1a.exe
               5 File(s)  1 127 302 494 bytes

There is a gDEBugger-5_8.msi file amongst listed ones, which apparently does not have any 1 character in it.

Everything becomes clear when I use /X switch with the dir command, which makes dir use 8.3 file names. Output from a dir /X *1* command:

 Volume in drive C is System
 Volume Serial Number is F061-0B78

 Directory of C:\Users\Piotrek\Desktop\Downloads


2012-05-20  17:33        23 639 040 GDEBUG~1.MSI gDEBugger-5_8.msi
2012-05-20  17:30           761 942 GLEW-1~1.ZIP glew-1.7.0.zip
2012-05-20  17:11         9 330 176 IRFANV~1.EXE irfanview_plugins_433_setup.exe
2012-05-24  20:17         4 419 192 SUMATR~1.EXE SumatraPDF-2.1.1-install.exe
2012-05-15  22:55         3 466 248 TRUECR~1.EXE TrueCrypt Setup 7.1a.exe
               5 File(s)  1 127 302 494 bytes

Quote from dir's help:

/X          This displays the short names generated for non-8dot3 file
            names.  The format is that of /N with the short name inserted
            before the long name. If no short name is present, blanks are
            displayed in its place.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!