MS-DOS 6.22 DOSKEY Macro Argument Parsing
In MS-DOS 6.22, the DOSKEY utility intercepts keyboard input to
expand user-defined macros before COMMAND.COM interprets
them. When a user runs a macro, DOSKEY parses any following command-line
text by splitting it into positional tokens, mapping them to predefined
replacement symbols such as $1 through $9 or
the global $* specifier. Understanding how this
substitution occurs clarifies how arguments, delimiters, and special
redirection characters are processed and passed to the underlying
command interpreter.
Intercepting the Command Buffer
DOSKEY operates as a Terminate-and-Stay-Resident (TSR) program that
hooks into interrupt vectors controlling keyboard input (specifically
standard buffered input, such as Interrupt 21h, Function 0Ah). When you
enter a command line, DOSKEY reads the input buffer before
COMMAND.COM receives it.
It isolates the first token—the command or macro name—delimited by whitespace. It then searches its internal memory structures for an identical macro name. If no match is found, the line is forwarded unmodified to the command processor. If a match is found, DOSKEY halts standard line evaluation and initiates macro argument expansion.
Positional Argument
Parsing ($1 through $9)
DOSKEY handles individual parameters via dollar-sign notation:
- Token Separation: DOSKEY scans the text following
the macro invocation. It identifies individual arguments by looking for
standard DOS command-line delimiters: spaces, horizontal tabs, commas
(
,), semicolons (;), and equals signs (=). Consecutive delimiters are collapsed into single separators. - Token Assignment: The first delimited string is
mapped to
$1, the second to$2, and so on, up to$9. DOSKEY supports a maximum of nine positional parameters. - Null Substitution: If a macro definition references
a parameter that was not supplied on the command line (for example, the
macro contains
$3, but only two parameters were entered), DOSKEY replaces the placeholder with an empty string rather than throwing a syntax error.
Global Argument Parsing
($*)
When a macro definition includes the $* symbol, DOSKEY
bypasses token-by-token splitting for that specifier:
- Unmodified Capture:
$*captures the entire tail of the command line immediately following the macro name. - Preservation of Whitespace: Unlike the positional
$1–$9parameters,$*preserves leading, trailing, and embedded spaces, as well as literal delimiter characters. - Coexistence with Positional Tokens: A macro can
include both positional tokens and
$*. In such instances, the positional arguments still receive their respective individual values, while$*simultaneously expands to the complete trailing argument string.
Handling Metacharacters and Redirection
Because standard DOS redirection characters (<,
>, |) and chaining characters execute
immediately if entered during the macro definition phase, DOSKEY relies
on dollar-prefixed aliases:
$Gor$g: Converts into the output redirection symbol (>).$G$G: Converts into the append redirection symbol (>>).$Lor$l: Converts into the input redirection symbol (<).$Bor$b: Converts into the pipe symbol (|).$Tor$t: Functions as a command separator, allowing multiple commands within a single macro.
During macro expansion, DOSKEY translates these dollar tokens into
their literal ASCII counterparts (>, <,
|). If $T is encountered, DOSKEY breaks the
expanded text into distinct sequential command buffers, queueing each
command to run in sequence.
Final Execution Hand-off
Once all token replacements ($1–$9,
$*) and metacharacter translations are finalized within
DOSKEY’s internal expansion buffer, the resulting string is placed back
into the system's standard input buffer. COMMAND.COM then
reads this translated string as if the user had typed the expanded
commands, arguments, and pipe/redirection operators directly into the
DOS prompt.