A batch file has no header, no signature and no structure beyond its lines. What makes it a batch file is its extension and the interpreter that is asked to run it. This page covers the file as bytes; the language starts at Lexical structure.
Extensions
| Extension | Used by | Notes |
|---|---|---|
.bat | MS-DOS COMMAND.COM, Windows cmd.exe, 4DOS, FreeDOS COMMAND.COM | The original extension, from MS-DOS 1.x onwards |
.cmd | Windows NT cmd.exe; OS/2 CMD.EXE | Introduced with Windows NT. On OS/2 a .cmd file is often a REXX program, which starts with a /* */ comment, so a .cmd is not always a batch file |
.btm | 4DOS, 4OS2, 4NT and Take Command (JP Software) | “Batch to memory”: the whole file is loaded before it runs. See Dialects and versions |
Microsoft’s call page says the file named after call must have a
.bat or .cmd extension. Two file names have a fixed role:
AUTOEXEC.BAT– run byCOMMAND.COMat start-up in MS-DOS and Windows 9x. Windows NT reads the environment variables and paths set in it (the Microsoftcmdpage lists it among the sources of variables).AUTOEXEC.NT– run when a 16-bit DOS program starts under Windows NT; the Microsoftsetpage sayssetis often used in it. It is written like a batch file.
.bat against .cmd
cmd.exe reads a .bat and a .cmd file with the same
parser, the same commands and the same syntax. The difference reported by SS64 and others
is in ERRORLEVEL: a few commands that change the environment or the file
associations (the reported list includes set, path,
prompt, assoc and ftype) always set it in a
.cmd file, but in a .bat file they set it only when they fail.
Microsoft’s pages do not describe this, so it is given here as reported, not checked. See
Errorlevel and exit codes.
COMMAND.COM does not know .cmd at all: it runs only
.com, .exe and .bat files.
How the file is found
Typing a name runs the first match: a command built into the interpreter, then a file in
the current directory, then a file in each directory of PATH. If no extension
is typed, cmd.exe tries each extension of the PATHEXT variable
in turn. A usual value is .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC,
so build runs build.exe before build.bat.
COMMAND.COM tries .COM, then .EXE, then
.BAT.
When a batch file is run by typing its name, control does not return to the file that
typed it: the new file replaces it unless it is run with call
(see Parameters and labels).
How the file is read
The interpreter reads the file again from disk for each command, remembering the byte
offset of the next line, not the whole text. This is why a batch file can be edited while
it runs, with odd results, and why goto searches for its label by reading the
file from the start. A .btm file is the exception: it is loaded once.
Because the file is not compiled, a syntax error is found only when the line that holds it is reached.
Encodings
- Code page, not Unicode. A batch file holds one byte per character (or
two for a double-byte code page) and is read in the console’s active code page, the OEM
page of the system (437, 850, 866 and so on) unless
chcphas changed it. The same bytes mean different characters on another computer. A file with accented characters, written in a Windows ANSI editor, shows them wrongly when run. - UTF-8. After
chcp 65001the console’s code page is UTF-8, and a batch file saved as UTF-8 without a byte order mark can then hold non-ASCII text in its strings and file names. Thechcpcommand has to run before such text is read, so it goes near the top of the file and the lines before it stay ASCII. - Byte order mark. A UTF-8 file that starts with the bytes
EF BB BFis widely reported to make the first command fail, because those bytes become part of its name (for example@echo). Save batch files without a mark. - UTF-16. Not supported: a file that starts
FF FEorFE FF, or that holds a zero byte after each letter, is not read as batch text. - Output encoding.
cmd /amakes output ANSI andcmd /umakes it UTF-16, which affects redirected files, not the script file.
The viewer reads a batch file as text in the encoding it detects and treats each character alike, so a code page does not change the colouring.
Line ends and Ctrl-Z
- CR LF. The line end of DOS and Windows text, bytes
0D 0A, and what every batch file should use. - LF alone.
cmd.exeruns a file that uses bare line feeds, but a file with Unix line ends is widely reported to breakgotoandcall :labelwhen the label falls across a boundary of the buffer the interpreter reads in. Keep CR LF. - Ctrl-Z. The byte
1Awas the end-of-text marker of DOS text files, written after the last line by old editors.typestops there on DOS. Whether the interpreter stops reading at it is not documented. The viewer reads it as white space. - A last line without a line end is still run.
- NUL bytes have no meaning in batch text, and the viewer shows a file that holds them as binary.
Limits
- Microsoft says the longest command line
cmd.exehandles, after variables are expanded, is 8191 characters, in a batch file as at the prompt. The same limit applies to each environment variable it inherits. - Older documentation gives 127 characters for
COMMAND.COMon MS-DOS; this was not checked against a primary source here. - Microsoft’s
forpage says no more than 52 loop variables can be active at a time. - Nesting of parenthesised blocks and of
callis limited by memory and stack, not by a documented number.
Running a batch file
Nothing marks a text file as a script except its extension and, for a file that is run
directly, the association Windows has for it. A batch file started from the desktop is run
by a new cmd.exe as cmd /c "file.bat" and the window closes when it
ends; cmd /k keeps it open. The cmd options that matter to a
script are:
| Option | Effect |
|---|---|
/c string | Run the command and exit |
/k string | Run the command and stay open |
/s | With /c or /k, strip the first and last quote of the string |
/q | Turn echo off |
/d | Do not run the AutoRun registry commands |
/a, /u | ANSI or Unicode (UTF-16) output |
/t:bf | Background and foreground colour |
/e:on, /e:off | Enable or disable command extensions |
/f:on, /f:off | Enable or disable file and directory name completion |
/v:on, /v:off | Enable or disable delayed variable expansion |
Without /d, cmd first runs the commands in the AutoRun registry
value under HKLM\Software\Microsoft\Command Processor and
HKCU\Software\Microsoft\Command Processor. The EnableExtensions
values under the same keys set the default for command extensions. All of this is from the
Microsoft cmd page.
A file as bytes
@echo off
rem Written with CR LF line ends and no byte order mark.
chcp 65001 >nul
echo Grüße
pause
65 63 68 6F 20 47 72 C3 BC C3 9F 65 0D 0A in UTF-8: ü is C3 BC and ß is C3 9F.Not described
Unknown
- Reference: whether
cmd.exestops at a Ctrl-Z byte, the exact buffer behaviour behind the Unix line end problem, the 127-characterCOMMAND.COMlimit and the list of commands that differ between.batand.cmdwere not checked againstcmd.exeor a Microsoft page.