logo To Foot
© J R Stockton, ≥ 2009-07-21

MS-DOS Batch Introduction.

No-Frame * Framed Index * Frame This
Links within this site :-

Until 2006-10-14, I used Win98 1st Edn.
From 2006-10-19, I used Win XP sp2; from 2008-07-06, XP sp3.

This page is about the language itself, as implemented by Microsoft in MS-DOS proper and in Windows up to Win98 (and, I believe, ME); but it does not deal with Windows NT, XP and later.

MS-DOS Batch

Some people started using computers, as I did, in "Deck-of-Cards" or "Roll-of-Paper-Tape" days; many more were using MS-DOS-like command lines long before Graphical User Interfaces became common. We are accustomed to the idea of using a command script to automate tasks. But users nowadays start with the Windows GUI (Graphical User Interface), and may know nothing of "C:\>". This section is mainly for them.

MS-DOS

During the decade or so from the introduction of the PC (in 1981) up to the prevalence of Windows, control of a PC was by way of command-lines typed at a "MS-DOS prompt" (typically "C:\>" or "DIRECTORY>") on a scrolling text display; this was inherited from previous practice with typewriter-like consoles.

Batch scripting provided, and still provides, a way in which the user can put a collection of such commands into a simple program file which is executed by entering its name and parameters. In MS-DOS, such a file is "filename.BAT" and can be executed by entering the line "Prompt> filename parameters".

Microsoft DOS exists in versions 1.0 to 6.22, and is simulated within versions of Microsoft Windows (as MS-DOS versions 7 or higher); I will assume those here (I have in use Amstrad DOS 3.30, MS-DOS 6.20, and Windows 98). There are other, rarer, implementations of DOS - some are similar, some are substantially enhanced (IBM PC-DOS, Caldera DOS, 4DOS, etc.). The versions in Windows NT and after are significantly different.

MS-DOS has two major components; an underlying I/O and program-loading system, and a Command Processor. The latter is really just a default program, COMMAND.COM, which deals with implementing keyboard commands. Commands are either internal, which are implemented within COMMAND.COM, or external, which are implemented by executable files supplied by Microsoft, vendors, or users.

A command processor can load and run, as an ordinary program, another copy of itself, or another command processor - "a secondary shell". Thus Windows NT, whose standard CP is CMD.EXE, has COMMAND.COM, and MS-DOS can run the CP of 4DOS.

MS-DOS Batch files are interpreted by COMMAND.COM (though "compilers" do exist). A Batch file, like scripts in general, is a plain text MS-DOS file, formatted only with new lines, spaces, and tabs. Commands type and more show whether a file can be considered as plain text.

Internal Commands

Internal commands are implemented within the Command processor itself. Searching COMMAND.COM for, say, the word CTTY will disclose the internal help for CTTY and a list of commands.

My Win98 lists :- DIR CALL CHCP RENAME REN ERASE DEL TYPE REM COPY PAUSE DATE TIME VER VOL CD CHDIR MD MKDIR RD RMDIR BREAK VERIFY SET PROMPT PATH EXIT CTTY ECHO LOCK UNLOCK GOTO SHIFT IF FOR CLS TRUENAME LOADHIGH LH LFNFOR. Some are only applicable within batch files.

External Commands

These are essentially the COM, EXE, and BAT files on the Path when MS-DOS, but not Windows, is first installed - which is ill-defined in Win9x or later, for which just most of those in C:\WINDOWS\COMMAND\ would normally be considered as belonging to the MS-DOS sub-system.

In my Win98, this includes :- DISKCOPY.COM EDIT.COM KEYB.COM MODE.COM MORE.COM SYS.COM ATTRIB.EXE CHKDSK.EXE DEBUG.EXE DELTREE.EXE FC.EXE FIND.EXE LABEL.EXE MEM.EXE MOVE.EXE NLSFUNC.EXE SORT.EXE SUBST.EXE XCOPY.EXE XCOPY32.EXE.

The MS-DOS Prompt

Loading ("booting") a plain MS-DOS system provides, finally, an MS-DOS prompt from the Command Processor. A Windows 3 system is started from a MS-DOS prompt (this can be automated within "AUTOEXEC.BAT"); a later Windows system can be made to boot to a MS-DOS prompt "instead".

But a good way to operate is to start Windows, and then to start one or more "MS-DOS boxes" (a.k.a. D.V.M. or DVM) by selecting the corresponding icon or menu entry. Such MS-DOS boxes are, to a first approximation, independent MS-DOS machines operating on a communal file structure. They can be used at the same time as GUI programs are being used; and they can start (or be started by) GUI programs.

The command line is limited to about 127 characters, and that is the most that can be passed to an external program by the traditional method using the "PSP". Longer lines are sometimes handled through the Win9x+ "CMDLINE=..." environment variable.

Help

Later true MS-DOS systems have a command "HELP [command]" ("[" & "]" enclose optional items). In most systems, brief help on a specific standard internal or external command is given on entering "command /?". This is very useful. Try "command /?" for help on COMMAND.COM itself; and try "win /?".

File Types

MS-DOS keeps no "type" information for files. Programs can choose to operate on a file treating it as text, in which case the character pair CR LF is used for "New Line" (contrast UNIX and Mac conventions), and Ctrl-Z (^Z) terminates reading.

Device and File Names

Device and file names are similar; device names are those found on a list within MS-DOS, and are directory-independent (if the directory exists). The device NUL exists to do nothing.

Device names include NUL CON PRN AUX LPT1... COM1... CLOCK$, but the list can be extended.

Drive names are single letters, consecutive by default, normally followed in use by a colon.

MS-DOS stores names in Upper Case, and treats lower case as equivalent.

Wild-Cards

In file names, '?' matches any character, and '*' matches any characters to the end of the field. Wildcard expansion is done within programs, not at the command line. Other systems are more potent.

Long File Names

Traditional MS-DOS file names (SFN) are limited to short "8.3" format; lower-case letters a..z are converted to upper-case A..Z, and spaces cannot be included. In 32-bit systems (Windows 95 & after) one can have LFNs, including spaces. In LFNs, case is stored, but the cases are generally treated as equivalent. Where an LFN may be referred to, use enclosing double quotes, as in dir "\program files" .

In traditional DOS systems, directory entries are 32 bytes; that holds the SFN, location, size, date, and attributes. LFNs, introduced in Windows 95, use additional entries, one for each 13 characters of the LFN. That can be important in filling the fixed-size root directory, especially for a floppy disc.

Renaming to a LFN can cause the directory entry to move, upsetting loops and scans.

The short version of a LFN is not stable under Move or Copy, or editing the file with backup.

NOTE that the SFN path cannot be deduced from the LFN path without further information, since the numeric part depends on the history of the machine.

In Win98, file operations (dir, copy, ...) with wildcards match against both SFN and LFN. For some systems, DIR /Z may match only SFN.

Don't use LFNs, if it can be avoided.

See also MS-DOS Batch Programs Page.

Temporary Files

In DOS..Win98, pipes use their own quaintly-named pairs of temporaries, usually not seen. The names appear to be the creation time, HHMMSScc, with each field in Hex, but using A..P for 0..F. Try dir %temp%\A*. | find "/" (use B*. from 4 p.m.; find the local date-field separator). The time is taken from the MS-DOS software clock, therefore changing at 55 ms intervals; so only $1800B0 = 1573040 names, rather than 8640000, are possible. Use pipetime in programs/ to interpret the times.

Where a batch file needs to use an explicit temporary file (which is faster), name it distinctively; I use an initial '$' in the name for short-term files, and more '$' in temporaries. F-PS has suggested replacing the first character of the batch file name with '$', the last with '0'-'9', and the extension with 'TMP'; putting temporaries in %temp%. In any case, using a name which does not look more or less like a word makes the code referring to it unnecessarily hard to read.

Limits

For reasons of speed, the number of entries in a directory must not be too big; searching is linear.

The FindFirst/FindNext finctions (see D-214E in Ralf Brown's List, *.g) use a data structure containing a 16-bit file counter. But something appears to be wrong with Int 21 4E/4F in MS-DOS 6.20, as shown by DIR & HUNT; it seems that the count may be treated as signed, so keep below 32768.

The Environment

The Command Processor uses an area of RAM called its Environment, in which are kept entries of the form "NAME=value". To see the contents, type "SET<enter>" at a Prompt; to add or change an entry, use "SET name=value". A command line containing "%name%" has that replaced, before execution, by the corresponding value.

Tech: A PSP entry points to the list. The null-terminated entries are consecutive, and terminated with another null, which may be followed by owner information ?

In being loaded, an instance of a program inherits a copy of the environment of its parent; it can easily read from, and, (for a HLL) less easily, write to, that copy. A Windows DOS box is a program; changes to its environment have no effect outside the box.

An ancestor's environment (sometimes "the MS-DOS master environment") can only be changed by specialised code. Mostly I now use that in jrs_envu.pas, which is known to work in MS-DOS to Win98. But NT, etc., are different.

I don't know of an authoritative list of environment variables which are used by MS-DOS .. WinME and commonly-used general utilities; I do know of the following candidates :-

with others for DR-DOS, 4DOS, NDOS, IBM-DOS, Win-NT, Win-XP, etc.

Caveat

The environment can be preloaded with settings that affect the running of standard, or other, utilities. For example, set dircmd = /p will include the more effect in the dir command. Batch file users should keep aware of this possibility.

The Path

There is an Environment variable PATH (to list all such, type "SET<enter>" at a Prompt; for just the Path, "PATH<enter>"); it gives a list of directories in which a command, if not MS-DOS internal, will be sought. External commands are implemented by files *.COM, *.EXE, *.BAT - the first two are "code", the third is "script"; the extensions are not typed.

Using LFNs in the Path seems to work; but can break batch code.

Batch File Creation & Editing

Just use a MS-DOS editor such as EDIT, or any Windows editor that saves in plain MS-DOS text. Notepad is suitable; but there are many better editors; I often use PFE. Name the file "filename.BAT". Use spacing and indentation for readability.

MiniTrue is useful not only within a batch file, but as a tool for making systematic changes to a file.

Batch File Contents

Read a more complete description; and see also in MS-DOS Batch Files. Some points :-

Commands with a leading @ are not echoed to the screen. The meaning of ECHO ON & ECHO OFF should now be guessable. ECHO. echoes a blank line.

Since % is a special character, it needs another representation, which is %% .

The parameters given to a batch file are represented, within it, by %1..%9; SHIFT moves them all down one number, losing %1.

If, within a batch file, another batch file is invoked by filename , that file is jumped to without return. But if it is invoked by CALL filename , it is called as a subroutine and, when it finishes, control returns to the next statement of the calling file (CALL is only from MS-DOS 3.3???; before, use COMMAND /C).

Input and output redirection, and pipes, are as at the MS-DOS prompt; they use respectively "<" (read), ">" (write), or ">>" (append), and "|" (pipe). They operate only on "standard" input and output (i.e. through the MS-DOS device "CON"?). Note that these are active within a REM comment, which can have disconcerting results.

Labels start with a colon; a label line is ignored, except when sought as the target of a GOTO. Therefore, a safer way to start a comment is with ":: "

Remember that an ERRORLEVEL test is an "at least" test, not an "equality" one. Generally, test the highest possible number first, as in if errorlevel 3 goto label3.

MS-DOS commands themselves are fundamentally independent of the language and locality for which the machine is set. However, their parameters, and the text resulting from their execution, can vary with setup; therefore, anything processing this text can be setup-dependent. As well as wording being in different languages, date, time, and number formats may vary.

MS-DOS command defaults may have been changed by the user; consider the effect of SET DIRCMD=/W, and therefore use DIR /-W ....

In a Win32 DOS box, as well as "." referring to the current directory and ".." referring to the current directory, "..." is the grandparent, "...." the great-grandparent, ...?

Filters

A Filter is a program which reads standard input and writes standard output; the output is usually a modified copy of the input. MORE, FIND, and SORT are supplied with MS-DOS. Some filters (e.g. FIND) can be given file names to use.

ANSI.SYS

The MS-DOS driver ANSI.SYS can be loaded at boot time; it interprets escape sequences in standard output to screen. Some find it useful.

Auxiliary Programs

Pure MS-DOS batch provides limited facilities. Much more can be done using also suitable auxiliary programs.

An Example File

To configure a new MS-DOS box (MS-DOS Prompt) :-

  dir
  @PATH=c:\utys;c:\homepage\programs;%PATH%
  @PATH
  set MINITRUE= -v:brwh::Grbk:::bkye -x-
  doskey /insert
  @cd homepage

Alternatives

There are other scripting systems, about which I know a little (I still use MS-DOS, and disfavour solutions requiring Win32); see in my MS-DOS Batch Files.

More

Test Whether a File Contains a Given String

This is a standard method, adapted from code in tsbat.zip :-

set FOUND=false
type SomeFile.txt | find "TheString" > $1.$$$
copy $1.$$$ $2.$$$ > nul
if exist $2.$$$ set FOUND=true
for %%f in ($1.$$$ $2.$$$) do if exist %%f del %%f
echo FOUND %found%

Test the Current Time or Date Against Ranges

This is written on the assumption that the time format is 24-hour and the date format is also ISO 8601. If not, either the format can be rectified (perhaps by COLS) or intervals must be handled by separately-coded sections.

A way to compare the present time with a constant range, using only native MS-DOS facilities, is

echo. | time | find "Current" > $0.$$$
echo Current time is   8:30:00* >> $0.$$$
	:: use any number of starred times
echo Current time is  17:45:00* >> $0.$$$
sort < $0.$$$ | find /n /v "*" > $0.$$$
type $0.$$$

then test for the presence of the string "[2]". If your DOS is not set for English, adapt the code.

The devices CON and NUL seem always to appear brand-new. Therefore

HUNT CON f#12 b#19 e

will set Errorlevel 0 if the time is in the range 12:00:00 to 18:59:59, otherwise 1.

My NOWMINUS can also be used; see Example 12 in NOWMINUS.TXT.

Windows XP Batch

Windows XP includes two command processors - CMD.EXE and a version of MS-DOS's COMMAND.COM.

See also MS-DOS Batch Files, MS-DOS Batch Programs.
Home Page
Mail: no HTML
© Dr J R Stockton, near London, UK.
All Rights Reserved.
These pages are tested mainly with Firefox 3.0 and W3's Tidy.
This site, http://www.merlyn.demon.co.uk/, is maintained by me.
Head.