I couldn't find anything but is there any reason for choosing %
over $
like in *nix shells?
3 Answers
By using a \
as path separator, they needed a different marker for control character encoding, and did choose $
which in turn meant that the variable marker need to be another one, which turned out as %
.
So by choosing %
instead they could have kept $
for variables, but then again is the parser structured a bit different as it allows concatenated strings, thus needing a finishing marker at the end of named variables. So they didn't and the rest is history :))
I'm not complete so sure right now about the full implications, but $
is used at least in three different ways on the MS-DOS command line and in batch.
- Expand a batch variable to a full path name with
%~$PATH:<varnumber>
- Defining special content for the PROMPT command like date and time as in
prompt $d $t$g
. - Code the escape character in parameters as
$e
likeecho $e[0m
for screen reset.
Especially the does give the lead here, as marking special characters in Unix is done via a backslash \
, which in DOS marks a directory level. MS had to use $
instead, so \e
became $e
.
Further, but way later (DOS 5)
- DOSKEY used
$
to indicate special functions in macro generation.
Surprisingly, its predecessor CP/M did use $
as variable indicator as well as marker for special meanings in some commands (like privileges in STAT
).
In CP/M batch files are run with the SUBMIT
command, which will read a file (standard ending .SUB
) and feed each line to the OS, after replacing variables marked with $
. DOS has this feature build in and treats .BAT
files like programs.
-
2
-
1CP/M's CCP doesn't give
$
any special meaning.STAT
andSUBMIT
are transients (separate programs) that interpret command-line parameters or strings in the input themselves.– BlrflAug 14, 2018 at 13:28 -
4@phuclv Remember that bash is a Johnny-come-lately; that strategy is of a far more ancient lineage.– tchristAug 14, 2018 at 13:28
-
1The
%~$PATH:<varnumber>
syntax is only supported bycmd.exe
, it was never available in DOS. And the bit about ‘control character encoding’ makes no sense. COMMAND.COM has no escape syntax for command lines (other than%%
for the%
character, and the syntax of thePROMPT
variable). Sep 2, 2020 at 8:58 -
1So the use of
-
changed the use of/
, which changed the use of\
, which changed the use of$
, which changed the use of%
. There's a hole in my bucket, dear Liza, a hole. Sep 2, 2020 at 18:49
Because it was already reserved for batch file command-line parameters.
Early DOS versions (1.x) did not support environment variables at all. They did, however, support batch files and parameter substitution using the %n
syntax (source). The character %
was already reserved for that purpose, and already had to be escaped as %%
in batch files; it made sense to re-use it for variable substitution, as the two features are quite similar.
The $
character, on the other hand, was already in use in names of temporary files, for example in EDLIN (source; the public source code is from the 2.0 version of DOS, but the binary in the v1.25/bin/
directory contains equivalent code, offset +0xd0 in the binary); subsequent DOS releases added more such uses. If the $
character were used for variables and the user wanted to delete a leftover temporary file with such a name (or, especially, if they wanted to have a batch file do it), the $
character would have to be escaped, which would be inconvenient (not to mention it would pose a slight backwards incompatibility). I am under the impression that Microsoft wanted to avoid adding more escape sequences to COMMAND.COM syntax, from the fact that for example they outright banished <
, >
and |
from file names when pipes were introduced.
Of course, that in turn raises the question why %
was used for batch file parameters instead of $
, like in the equivalent CP/M functionality provided by the SUBMIT command. Batch files are supported in MS-/PC DOS 1.x, but apparently not in 86-DOS 0.3; the manual makes no mention of it. So it appears the functionality was added sometime between those two versions; this is confirmed by the 86-DOS license agreement between Microsoft and Seattle Computer Products, which mentions ‘SUBMIT facility comparable to CP/M’ as one of the improvements to 86-DOS that Microsoft requested from SCP. Perhaps %
was chosen for reasons similar to the above; per the manual, 86-DOS 0.3 already contained EDLIN, and so we may surmise that $
was already being used as a file name character back then. But to be sure you’d probably have to ask Tim Paterson; otherwise your guess is as good as mine.
-
Answer can be improved: at some point ^ was added to escape. When was that?– JoshuaDec 12, 2021 at 22:29
-
1No earlier than in Windows NT, maybe OS/2. No version of MS-DOS supported it. Dec 12, 2021 at 22:41
-
1In many DEC systems, '$' was used as a reserved-to-DEC character in symbol names, as a primitive way to separate the namespace into DEC-use and customer-use. The 'softies would be familiar with this, and I think that's how '$' is used in DOS etc. Dec 17, 2022 at 12:27
I can't know for sure but I suspect one of the reasons was that $
was used as the string terminating character in the standard DOS "print string" API (int 21h ah=9h
), a convention apparently inherited from CP/M.
-
3
%
instead of$
, but the syntax is different. In *nix, the dollar sign is a sigil, and the percent sign in MS-DOS is more like a magic quotation mark, as variable names must be enclosed in percent signs to be interpolated, rather than just preceded by a percent sign (e. g.%PATH%
). This avoids the need to have another magic character, like parentheses to indicate the variable name boundary, like in$(foo)bar
. Then it makes sense to use a new character to indicate its new semantics.$(foo)
means "run commandfoo
and insert itsstdout
put into the command whereas (in POSIX shell also)${foo}
means "value of variable$foo
.