MS-DOS 7 系统编程入门/内部命令
第三章 内部命令
内部命令是由命令解释器本身执行的命令。与其他需要搜索和从其介质读取的实用程序相反,解释器永久驻留在内存中,因此内部命令执行得更快。由于内部命令无需搜索,因此无需指定内部命令的路径。所有内部命令的另一个共同属性是它们不返回错误级别代码。
本章介绍 Microsoft 专有命令解释器 COMMAND.COM 的内部命令(文件大小 93812 字节,文件日期 1996 年 6 月 12 日)。此解释器的本地化版本通常略大,日期略晚,但仍然执行相同的内部命令集。在所描述的内部命令中,有专为批处理文件设计的命令(3.02、3.14、3.21、3.27)。
COMMAND.COM 解释器为其内部命令提供简短的帮助信息。要显示帮助文本,您必须键入命令名称,后跟一个空格和 /?
参数,然后按 ENTER 键。但是,提供的简短帮助信息通常被认为太短。本章提供了一些说明,可以帮助您避免常见错误,并使内部命令的使用更加有效。
BREAK 命令类似于同义配置命令(有关详细信息,请参见 4.02)。它们都影响相同的二进制标志,该标志控制在磁盘访问操作期间对 BREAK 和 CTRL-C 键击的检查。当命令解释器的当前驻留模块完成其工作时,此二进制标志不会丢失其状态,并且本地环境将丢失。与 IO.SYS 加载程序 (4.02) 相反,COMMAND.COM 解释器在响应不带参数的 BREAK 命令时会显示所述二进制标志的当前状态。
CALL 是一个从另一个批处理文件(主批处理)执行一个批处理文件(次要批处理)的命令。批处理文件是非格式化的文本命令文件,COMMAND.COM 解释器从中接受扩展的命令集。CALL 命令只是其中一个旨在从键盘而不是从批处理文件行输入的命令。
批处理文件中的每一行都可能包含一个内部命令的名称,或一个外部实用程序的名称,或另一个批处理文件的名称。当命令解释器遇到一个外部实用程序的名称时,它会将控制权转移到该实用程序,但在实用程序完成其工作后会收回控制权,并继续执行同一个批处理文件中的下一行。但是,批处理文件不像普通实用程序那样工作。在批处理文件(主批处理)的一行中找到一个批处理文件(次要批处理)的名称后,COMMAND.COM 解释器会开始执行次要批处理,并且不会返回到主批处理。为了能够返回到主批处理文件的执行,次要批处理应使用 CALL 命令启动,例如
CALL C:\DOS\VC4\Help.bat J 96
其中
C:\DOS\VC4\ – HELP.BAT 文件的路径示例。如果省略路径,则将在当前目录中搜索该文件,然后根据 PATH 变量指定的路径进行搜索。 | ||
Help.bat |
– | 次要批处理文件的名称示例。 |
J 96 |
– | 要传输到 HELP.BAT 文件的特定参数(其他批处理文件可能需要其他参数,或者可能根本不需要参数)。 |
实际上,CALL 命令会阻止关闭主批处理文件,会保留主批处理文件的存储段、其虚拟参数和其文件指针位置(作为返回目标),让命令解释器执行 CALL 命令后在同一行中指定的另一个(次要)批处理文件,然后恢复对主批处理文件需求的访问,从而能够返回到主批处理文件中下一操作的执行。
- 注意
- 次要批处理文件不是继承主环境的副本,而是继承对相同主环境的访问。在次要批处理文件执行期间分配的变量的值将在恢复主批处理文件执行后变得可访问。
- 使用 CALL 命令执行批处理文件允许嵌套超过两次。
- CALL 命令允许执行递归调用,即,可以从同一个批处理文件中的行中调用一个批处理文件。但是,用户有责任防止递归嵌套级别的不受控制的加深。
- 如果次要批处理文件未在指定的目录或当前目录中找到,以及在 PATH 变量定义的所有路径中都未找到 (2.02-02),那么执行将转移到主批处理文件的下一行,而不会出现任何错误消息。
- 在使用 CALL 命令的行中不允许重定向符号 (2.04-02 - 2.04-05)。
- 所述 CALL 命令是为 COMMAND.COM 解释器设计的,不应与同义汇编命令 (7.03-08) 混淆,后者由 DEBUG.EXE 调试器解释。
当命令行中未指定磁盘和路径时,MS-DOS 隐含地假设所寻址的对象位于默认(当前)磁盘的默认(当前)目录中。默认磁盘分配已在第 2.04-01 文章中进行了说明。默认目录分配由 CD 命令执行。
CD 命令允许根据指定路径更改任何磁盘上的当前目录(但不能更改当前磁盘本身)。例如,命令
CD C:\DOS
如果当前(默认)磁盘是 C 盘,则会将当前目录设置为 \DOS。CD 命令可以指向非当前磁盘,但指定的路径会被视为预设,当 CD 命令中指定的磁盘被设置为当前磁盘时,该预设路径将成为当前(默认)目录 (2.04-01)。
CD 命令中的路径可以以任何允许的形式表示 (2.02-01)。路径中的最后一个词必须是目标目录的名称或任何别名符号的组合 (2.02-03, 2.03-02)。这些组合可以执行以下操作:进入根目录 (CD \
)、进入父目录 (CD ..
)、向上遍历目录结构两级 (CD ..\..
) 等等。
没有路径指定的 CD 命令,例如
CD C:
显示指定磁盘上当前目录的路径。如果磁盘也不指定,则隐含当前磁盘。
- 注意
- CHDIR 是与 CD 命令相同的另一个有效名称。
- 通过 CD 命令分配为当前目录的目录无法使用 RD 命令 (3.23) 删除,即使该目录不属于当前磁盘。
- 所有逻辑磁盘的当前目录的预设路径存储在 CDS 表结构 (A.03-3) 中。默认情况下,它填充到根目录的路径。
3.04 CHCP – 更改代码页
[edit | edit source]代码页是用于在屏幕上显示消息的字符和符号数组。当使用 CHCP 命令而不带后面的代码页编号时,它将显示当前活动代码页的编号。更改代码页的功能通常被禁用,
- 除非 DISPLAY.SYS 驱动程序 (5.02-02) 准备了两个或多个代码页内存缓冲区,
- 除非这些缓冲区已通过
MODE.COM CON CP PREP
命令 (6.18-03) 用不同的代码页填充, - 并且除非事先加载了 NLSFUNC.EXE 驱动程序 (5.02-03)。
惯例是只加载一个国家代码页,因为每个国家代码页不仅包含国家字符集,还包含美式英语字符集。在这些字符集之间切换并不意味着代码页更改:它是在任何一个国家代码页内部执行的。
当没有一个代码页包含你要使用的语言的字符集时,就需要加载多个国家代码页。例如,如果你准备了挪威代码页 865 和俄罗斯代码页 866,那么命令 CHCP 865 和 CHCP 866 将在这些代码页之间执行切换。
- 注意
- 可以使用
MODE.COM CON CP SEL
命令 (6.18-03) 更改代码页,该命令不需要加载 NLSFUNC.EXE 驱动程序。 - CHCP 命令无法处理由非微软驱动程序加载的国家代码页,例如由 KEYRUS.COM (5.02-05) 加载的代码页。
- 如果你使用某个重要实用程序或 TSR shell 的国家版本(例如,使用俄语符号的 Norton Commander),那么更改代码页将使这种国家符号完全不可读!只有美式英语符号(字符 32 – 127,所有代码页共用)不会受到代码页更改的影响。
3.05 CLS – 清除屏幕
[edit | edit source]CLS 命令会清除显卡内存中当前屏幕页的所有内容,并将其颜色设置为默认值,从而实现黑色背景上的白色文本显示。
3.06 COPY – 复制文件
[edit | edit source]COPY 命令用于复制一个文件或多个文件。它还允许连接文件并组合复制和重命名。以下是将一个文件复制到另一个位置的示例
COPY /A C:\DOS\MS7\Trial.txt A:\DOS /V /Y
其中
/A |
– | 表示指定源文件必须复制到第一个文件结束符 (1Ah) 之前。要将一个文件复制到目标文件,默认情况下会使用相反的 /B 参数。它强制完整复制文件,忽略文件结束符字节 1Ah,该字节在可执行文件和二进制数据文件中可能起着完全不同的作用。 |
C:\DOS\MS7\ – 是源文件路径的示例。有关路径规范的允许替代形式,请参见 2.02-01 – 2.02-03。如果没有指定源文件路径,则只会从当前目录中搜索此源文件(COPY 命令会忽略 PATH 变量中的路径)。 | ||
Trial.txt – 是要复制的源文件名的示例。如果源文件名有扩展名,则必须指定扩展名。源文件可以具有 "A"(存档)和 "R"(只读)属性。不会复制具有 "H"(隐藏)和 "S"(系统)属性的源文件。 | ||
A:\DOS |
– | 是现有目标目录的路径示例,其中应放置副本。但是,如果 \DOS 目录不存在,则 DOS 将被解释为副本的新名称,并且将在 A 盘的根目录中创建一个名为 DOS 的副本。如果你不想重命名副本,则目标路径必须与源路径不同。如果源文件不在当前目录中,则可以省略目标路径,在这种情况下,当前目录将隐含为目标。 |
/V |
– | 是一个可选参数,它会强制验证副本。这会使复制速度变慢,并且在目标介质是硬盘时不需要。但是,当目标介质是软盘时,/V 参数可能值得延迟。 |
/Y |
– | 是一个可选参数,它允许在不提示的情况下覆盖目标目录中的任何同名文件。/Y 参数可以在 COPYCMD 环境变量 (通过命令 SET COPYCMD= /Y ) 中预设,这样你就不需要在命令行中指定它。当需要提示时,可以在命令行中使用 /–Y 参数覆盖此预设。 |
当 /A
参数是命令行中的最后一个项目时,它的作用完全不同:它不会阻止完整复制文件,而是会强制 COPY 命令在副本中追加文件结束符 (1Ah),如果该文件结束符不存在的话。
COPY 命令中指定的第一个路径始终被解释为源路径,最后一个被解释为目标路径。在一个 COPY 命令中指定两个以上的路径(或文件名)被视为错误,除非指定中间源文件,并在前面加上加号 ( + ) 用于连接复制,例如
COPY /B T1.dat + T2.dat /A + Remark.txt C:\DOS
其中
/B |
– | 复制模式参数,它在第一个源文件名之前,会保持其对所有后续源文件名的影响,直到遇到相反的参数规范 (本例中的 /A )。如果还有其他源文件名,则后者会将其影响传播到所有剩余的源文件名。由于连接主要应用于非可执行文件,因此 /A 参数被视为连接复制的默认参数。 |
T1.dat 、T2.dat 、Remark.txt – 这些是要连接复制的三个源文件。由于省略了源文件的路径,因此隐含所有这些文件都存在于当前目录中。除了第一个源文件名之外,所有后续源文件名前面都必须加上连接符号 ( + )。 | ||
C:\DOS |
– | 是目标目录路径的示例。如果目标目录存在,则连接结果将放置在该目录中,并且会继承第一个源文件 (T1.DAT) 的名称。但是,如果 C:\DOS 目录不存在,则最后一个名称 DOS 将被解释为组合文件的新的名称,并且将在 C 盘的根目录中写入名为 DOS 的连接结果。 |
允许使用文件掩码代替源文件名,但应谨慎使用这种规范。让我们考虑一个例子
COPY /B T*.dat C:\DOS\Concat.dat
COPY 命令检查目标路径中的最后一个词(最后一个反斜杠的右侧),以确定它是否是一个现有子目录的名称。如果子目录 CONCAT.DAT 不存在,则所有符合给定文件掩码的文件副本将被连接到一个新的文件中,该文件将在 C:\DOS 目录中创建,并将命名为 Concat.dat。但是,如果名为 CONCAT.DAT 的子目录已经存在,则所有符合文件掩码的文件将不会被连接,而是会逐个单独地复制到该子目录中。后一个例子表明,COPY 命令使你能够使用同一个命令行获得完全不同的结果。这就是为什么你必须确切知道你指定的最后一个名称是否与现有子目录的名称一致。
对于连接复制,可以将同一个文件指定为目标和第一个源文件,并且该文件将被追加到后续源文件的内容。不允许将非第一个源文件指定为目标(该源文件的内容将丢失)。当副本的新名称不会被误解时,则可以为源文件和目标指定相同的路径,甚至完全省略这两个路径(隐含当前目录)。
将一个文件复制到自身被视为错误。但是,连接复制的形式允许为未重命名的副本和源文件指定相同的路径。同时,可以省略连接的第二个文件的名称,例如
COPY /B \DOS\File.ext +,,\DOS
这种伪复制形式不会更改文件的内容,但用于将当前日期分配给文件,或者如果文件为空,则用于删除文件。[注 1][注 2]
COPY 命令中源文件位置的保留字 CON (= 控制台) 会导致命令解释器不将后续输入行解释为命令行,而是将后续输入解释为文本
COPY CON C:\DOS\Remarks.txt
此命令允许将从键盘输入的文本写入到在 C:\DOS 目录中创建的 Remarks.txt 文件中,直到按下 F6-ENTER 键组合返回命令行输入 (有关更多详细信息,请参见 1.04)。
保留字 PRN (打印机)、LPT1–LPT4 (并行端口)、COM1–COM4 (串行端口) 或 NUL (虚拟 "黑洞") 可以用作复制的目标,而不是文件。命令
COPY CON PRN
将计算机变成一台打字机。当然,必须正确配置所选目标,并且连接的终端设备必须能够响应 DOS 的请求。当目标是设备时,默认情况下会使用 /A
参数 (作为 ASCII 文本复制)。与真正的终端设备相反,虚拟设备 NUL 始终配置正确。将真实文件从物理介质 (例如,从软盘) 复制到虚拟 "黑洞" NUL 有时用于测试该文件是否为空或是否可读。
- 注意
CTTY 命令更改所有三个标准 I/O 通道的设置:STDIN、STDOUT 和 STDERR。初始的默认 I/O 设置等效于 CTTY CON 命令设置的那些设置:所有通道都与 CON 设备(控制台)链接,即与键盘输入和显示输出。CTTY 命令可以接受以下端口之一来代替控制台 (CON):COM1 (AUX)、COM2、COM3、COM4、LPT1 (PRN)、LPT2 以及虚拟设备 NUL(用于输出到“无处”)。CTTY 是一个古老的命令。它的名称(CTTY = Change TeleTYpewriter)让人想起没有显示器、I/O 控制台类似老式电传打字机的时代。
如今,在批处理文件中使用 CTTY 有两个原因。第一个是防止意外中断执行;第二个是防止通过 DOS 的 STDERR 通道发送的、无法以其他方式重定向的、不希望看到的错误消息。在这两种情况下,问题都通过重定向到虚拟 NUL 设备(无处)来解决:CTTY NUL 位于要保护的命令组之前,CTTY CON 稍后恢复与键盘和显示器的正常通信。在受保护的命令组(CTTY NUL 和 CTTY CON 之间)中,不允许内部和交互式中断执行,因为否则不会显示任何消息,不会接受任何输入,并且 PC 似乎会挂起。尽管如此,通常仍然可以通过 CTRL-ALT-DELETE 重启。
CTTY 命令只影响隐式 I/O 设置,但它不影响在命令行中显式指定的重定向(2.04-02 – 2.04-05)。例如,让我们考虑批处理文件的以下部分
@ctty nul copy /B Trial.dat Suit.dat echo Press any key to exit > con pause < con ctty con
这里来自 COPY 命令的消息将不会到达屏幕,即使它是错误消息。但是“按任意键退出”消息将显示,因为它被显式地定向到 CON 设备。下一个 PAUSE 命令也将正常工作,因为它被显式地链接到键盘。这种形式的 CTTY 使用需要谨慎,但它为影响与用户的交互提供了有吸引力的机会。本文 9.03-02 中展示了一个使用这种形式的 CTTY 的批处理文件示例。
- 注意
- 被 CTTY NUL 命令禁止后,STDERR(错误)消息无法被显式地重定向并且会丢失。
要设置新日期,必须在命令行中 DATE 命令的名称之后指定此新日期,例如
DATE 11.07.2002
当未指定日期时,将显示当前日期,然后系统将提示您通过键盘输入新日期。[注 2] 如果您不想更改日期,只需通过按 ENTER 键来响应提示。
字母和其他文本文件通常会附加一行带日期签名的行。为此,应以以下方式使用 DATE 命令
ECHO= | DATE | Find.exe "Current" >> Anyfile.txt
这里,第一个重定向 (ECHO= | DATE
) 会自动响应显示的提示并启用无停顿操作,第二个重定向 (DATE | Find.exe
) 会排除不希望看到的输出行,第三个重定向 (>> Anyfile.txt
) 会将日期签名附加到指定的文件。
当然,应该满足执行重定向 (2.04-05) 和查找文件 (Find.exe 和要附加的文件) 的所有条件。
- 注意
- 日期和月份数据的顺序是特定于国家的,应由 COUNTRY 命令 (4.05) 设置。
- ^ 更改日期的提示补充了一个用于两位数年份数据的提示,但这是一个错误 : MS-DOS 7 需要四位数年份数据。
DEL(DELete)命令不会物理删除文件,而是禁用目录规范中的文件条目。被无效条目占用的簇被认为是空闲的,并且可能在后续操作期间被覆盖。但在这些簇被覆盖之前,已删除的文件可以被恢复,例如,可以使用 Norton Utilities 版本中的 UNDELETE.EXE 实用程序来恢复。
这是一个带有 DEL 命令的命令行的示例
DEL D:\TEMP\Filename.ext /P
其中
D:\TEMP\ |
– | 包含要删除的文件的目录的磁盘和路径规范的示例。如果省略路径,则隐含当前目录。 |
Filename.ext – 要删除的文件的名称示例; | ||
/P |
– | 可选参数,在删除每个文件之前提示确认。 |
当指定文件掩码 (2.01-03) 而不是文件名时,将删除所有符合此文件掩码的文件。但是,尝试使用文件掩码 *.*
删除目录中的所有文件会导致停止并询问用户是否真的应该删除所有文件。即使未指定 /P
参数,执行也会停止。用户必须使用 Y(是)或 N(否)键来响应查询。
在批处理文件中,无停顿操作通常是可取的,不需要任何提示和查询。这可以通过以下方式实现,例如,在 FOR
循环中执行 DEL
命令
FOR %%Z in (*.*) do DEL %%Z
这种形式的循环始终显示已删除文件的列表(即使重定向到 NUL
)。您可以通过以下方式实现 DEL
命令来避免不希望看到的消息
ECHO Y | IF EXIST D:\TEMP\*.* DEL D:\TEMP\*.* > NUL
在上面的示例中,ECHO Y
命令提供了对查询的自动响应,而 IF EXIST
条件存在的唯一原因是当指定的目录 (D:\TEMP\
) 最初为空时避免“找不到文件”错误消息。
- 注意
ERASE
是与DEL
命令相同的另一个有效名称。- 具有属性 R(只读)、H(隐藏)、S(系统)和目录的文件无法使用 DEL 命令删除。要删除目录,应改用
RD
命令 (3.23)。 DEL .
命令(后缀为点)等效于DEL *.*
。DEL \
命令(后缀为反斜杠)在当前磁盘的根目录中删除所有不受属性保护的文件。
在 MS-DOS 中,DIR
(DIRectory)命令是探索目录内容的主要工具。这是一个带有 DIR
命令的命令行的示例
DIR C:\DOS /P /A:HS /O:GN /S /L /V
其中
C:\DOS |
– | 要探索的目录的路径示例。如果未指定,则隐含当前目录。 | ||||||
/P |
– | 可选参数,在输出数据的每屏幕满后停止,直到用户按下任意键。 | ||||||
/A:HS |
– | 一个参数,指定允许显示具有特定属性的项目:H (隐藏)、S (系统)、A (新文件或已更改文件,尚未保存在存档中)、R (只读)、D (目录)。可以使用前缀“–”来反转选择:–H (除隐藏以外)、–D (除目录以外)等等。/A 参数不带后续属性,强制显示目录中的所有项目。当省略 /A 参数时,不会显示隐藏文件和系统文件。 | ||||||
/O:GN |
– | 显示项目的排序顺序规范:G – 首先是目录、N – 按名称(默认)、S – 按大小(最小者优先)、E – 按扩展名、D – 按日期和时间(最早者优先)、A – 按最后访问日期(最早者优先)。可以使用前缀“–”来反转顺序:–N – 按名称(反向字母顺序)、–S – 按大小(最大者优先)等等。 | ||||||
/S |
– | 一个可选参数,强制显示子目录的内容。 | ||||||
/L |
– | 一个可选参数,强制将显示的文件名转换为小写,否则这些名称将按原样显示。 | ||||||
/V |
– | 一个可选参数,导致显示补充数据:属性、最后访问时间、分配的磁盘空间、总磁盘空间及其使用情况。其他参数优先于 /V ,它们是
|
DIR 命令可用于显示有关特定文件或所有符合给定文件掩码的文件的信息
DIR *.txt /P /S /B
在后一个示例中,路径规范的缺失与 /S
参数的组合意味着 DIR 命令实际上将在当前目录及其所有子目录中搜索 *.txt
文件。如果当前目录是根目录,则搜索将在整个当前磁盘中进行。如果您只对查找遗忘的文件感兴趣,/B
参数将使结果更简洁易懂。
DIR 命令的参数可以预设在 DIRCMD 环境变量中(例如,使用命令 SET DIRCMD= /P /S /B
),然后您将默认获得 DIR 命令的所需操作。如有必要,您可以在命令行中在其前面加上连字符“–”来覆盖任何预设参数(例如,/–P
)。
当 DIR 命令与 /A 参数一起执行时,*.*
文件掩码(所有文件)不排除目录。如果您只需要显示文件,则应该提供 /A: –D
参数。此功能使您可以探索目录(或磁盘)是否为空。例如,考虑以下批处理文件中的几行
@echo off set DIRCMD=/a /b dir *.* > C:\Temp\Found.lst copy C:\Temp\Found.lst NUL | Find.exe "0 file" > nul if errorlevel 1 echo Current directory is NOT empty if not errorlevel 1 echo Current directory is empty
第二行指定参数,以便 DIR 命令在测试目录为空时不显示任何内容。第三行将 DIR 命令的输出重定向到 FOUND.LST 文件。第四行的 COPY 命令不会复制空文件,在这种情况下会发出“复制了 0 个文件”的消息。FIND.EXE 实用程序通过重定向捕获此消息并将错误级别设置为零。接下来的两行用于感知错误级别并显示相应的条件响应。
当 DIR 命令在没有 /W
或 /B
参数的情况下执行时,它可能会以两种不同的方式显示文件名,具体取决于操作系统环境。在 WINDOWS 操作系统的 DOS 窗口中,文件名会“按原样”显示,但在 MS-DOS 7 环境中,文件及其后缀的名称会分开显示,文件名和后缀之间没有点。此功能可用作简单测试,以确定当前的操作环境。
- 注意
DIR \
命令显示根目录中的所有文件。- 在 DIR 命令显示过程中,可以通过按 CTRL–S 或 BREAK 键来停止屏幕上输出行的滚动;然后,在按任何其他键后,滚动将恢复。
3.11 ECHO – 通过 STDOUT 输出字符串
[edit | edit source]在 ECHO 命令名称之后同一命令行中指定的词语将作为消息发送到 STDOUT 通道;除非重定向,否则其默认终端点是 CON(控制台)设备,在屏幕上显示消息。ECHO 命令的字符串输出示例,特别是在上一篇文章 3.10 中有所显示。
要显示的消息最多可以包含 123 个字符。实际的消息长度受行本身或遇到的第一个重定向符号(2.04-02 – 2.04-05)限制。消息字符串可能包含 ASCII 服务标记,如附录 A.02-8 中所示。但消息字符串不能为空或以 ON 或 OFF 开头。这些和其他一些例外用于执行特殊功能
ECHO ON – 打开 ECHO 标志,允许在执行批处理文件行时显示它们(这是默认状态)。 | ||
ECHO OFF – 关闭 ECHO 标志(不显示任何行)。在批处理文件之外,这会导致命令提示符消失。 | ||
ECHO |
– | (没有后面的消息)显示 ECHO 标志的当前状态。 |
ECHO= |
– | (附加等号)– 通过 STDOUT 通道发送字节 0Dh 0Ah,就像按下 ENTER 键一样(文章 3.08 中的示例)。在屏幕上或文件中,这会导致插入空行。 |
ECHO+ |
– | 通过 STDOUT 发送字节 0Dh 0Ah,但如果存在,也会发送加号后面的词语,包括 ON 和 OFF。当 ECHO 命令附加斜杠或点时,它也会类似地起作用。 |
ECHO 标志是本地标志,保持其状态直到批处理文件共享公共环境,但此状态不会被继承,并且在命令解释器创建派生(子)环境时重置为默认值。
在默认 ECHO ON 状态下显示的命令行与批处理文件中的原始命令行不同:在显示的行中,所有别名都替换为它们的值。这对于调试很有用。但在文件已证明没有错误时,这不是必需的。因此,几乎每个完成的批处理文件都以 @ECHO OFF 命令开头。ECHO 命令之前的“@”字符将阻止显示该命令本身。
3.12 EXIT – 关闭当前解释器会话
[edit | edit source]命令解释器 COMMAND.COM (6.04) 是一个驻留程序,它为执行其他程序安排环境。另一方面,命令解释器本身可以像普通程序一样启动,以安排一个单独的(本地)环境,如果需要的话。在这种情况下,命令解释器的多个驻留模块可以同时存在于内存中,但只有一个可以处于活动状态 - 最后加载的那个。EXIT 命令关闭活动驻留模块的当前会话,释放模块占用的内存,并将控制权转移到父程序(启动了该驻留模块)。
当当前解释器会话关闭时,其包含所有值和变量的本地环境将丢失。同时,父程序的先前环境将再次可访问,并且该程序的执行将自动恢复。命令解释器的第一个驻留模块由 IO.SYS 加载程序使用 SHELL 命令 (4.26) 在 CONFIG.SYS 文件 (9.01-01) 中启动。这个第一个驻留模块无法将控制权转移到它的“父程序”,因为 IO.SYS 加载程序不是驻留的,并且已经完成了它的工作。如果命令解释器的第一个驻留模块能够执行 EXIT 命令,那么计算机将挂起。为了防止这种情况发生,COMMAND.COM 解释器必须第一次使用 /P 参数 (6.04) 启动,这将禁用 EXIT 命令。
3.13 FOR – 循环运算符
[edit | edit source]FOR 循环运算符安排其他命令的循环执行。例如,假设我们需要显示三个简短的文件:First.txt、Second.txt 和 Third.txt。与其使用单独的命令将这些文件发送到显示,不如使用 FOR 运算符,可以在一行中完成相同的事情
FOR %Z IN (First Second Third) DO TYPE %Z.txt
其中
%Z |
– | 循环变量名称的示例,它依次设置为括号中指定的每个项目。循环变量名称不应以数字开头。通常它是一个字母名称,前面带有一个百分号 ( % ),当循环从命令行执行时,或者带有一个双百分号 (%% ),当循环从批处理文件执行时。 |
IN |
– | 一个必需的保留字,引入括号中指定的变量值的以下列表。 |
DO |
– | 一个必需的保留字,引入以下要循环执行的命令的名称,循环次数与为循环变量指定的数值一样多。在每次迭代中,一个新值将替换循环变量的名称。 |
括号中的项目可以是任何词语,包括环境变量替换(例如 %TEMP%)和虚拟参数替换(2.03-03)。括号中的项目可以用空格、分号 ( ; ) 或逗号 ( , ) 分隔。请注意,PATH 变量值中的路径是用分号分隔的,因此 PATH 的值将被 FOR 循环分解成一组单独的路径。此操作通常用于确定给定文件是否可访问,或为其提供显式路径规范。批处理文件的以下部分显示了一个典型的路径确定示例
@echo off set P= FOR %%Y IN (. %PATH%) DO if exist %%Y\Fc.exe set P=%%Y\Fc.exe if %P%"==" echo Requested file hasn't been found! if not %P%"==" echo Path to the requested file is %P%
在这里,第二行将辅助变量 P 赋值为空值,第三行将指定文件的路径赋值,如果该文件恰好被找到。请注意,循环变量名称 (%%Y
) 前缀有一个百分号对,因为在批处理文件中必须这样。最后两行检查辅助变量值的存在,并根据结果发出相应的消息。
括号中的项目可以包含通配符 (2.01-03),但包含通配符的项目将被解释为文件名,应在当前目录中或根据前面的路径(如果指定)搜索。不隐含沿 PATH 变量中的所有路径自动搜索。括号中的几个项目中的每一个都可以包含通配符,例如
FOR %%X IN (A:\*.txt A:\*.doc) DO COPY /B %%X C:\DOS
有时需要单独显示 FOR 循环内执行的每个操作,但不显示循环本身。以下对前面示例的修改可以说明此机会
ECHO ON @FOR %%X IN (A:\*.txt A:\*.doc) DO COPY /B %%X C:\DOS @ECHO OFF
如果在括号中用通配符指定的文件未找到,则相应的操作将被跳过,没有任何错误消息。这就是为什么 FOR 循环有时被用作消除不希望出现的错误消息的手段(请参阅 3.09 的示例)。FOR 循环的另一个“副作用”是它能够解析环境变量的多词值,并消除该值中单独词语之前或之后可能存在的额外空格。
在括号内,一个字符串(包括分隔符)可以被视为一个项目,如果它被包含在双引号中(缺少结束引号被视为错误)。双引号本身不被视为属于项目。这使得可以在一行中指定多个不同的命令,例如
FOR %%Z IN ("set E=%W%" "echo E is set" "goto L23") DO %%Z
有一些操作序列无法在单独的行中执行,但可以在 FOR 循环内执行。此类序列的示例显示在文章 9.03-02 中的批处理文件的第 46 行,以及文章 9.01-03 中的批处理文件的第 6 行。
在括号内,包含在双引号中的命令可能包含变量值的替换(例如 %W%)、条件命令 (IF
)、跳转命令 (GOTO
) 和重定向 (2.04-02 - 2.04-05)。当从 FOR 循环内跳转到标签时,将跳过下一个操作(如果存在,则放在右侧)。FOR 循环内的重定向将其操作传播到所有后续命令。例如,在循环中
For %%Z in ("echo 1st line >> Q.txt" "echo 2nd line") do %%Z
“第二行”这个词不会显示在屏幕上,而是会被追加到 Q.txt 文件中。后续操作的重定向可以更改,但必须显式指定。
FOR 循环从其参数中删除包含双引号的能力不仅对于执行命令至关重要,而且对于显示消息也至关重要,这些消息受到双引号保护,不会被解析。
不允许嵌套 FOR 循环,但内部 FOR 循环可以由命令解释器 (COMMAND.COM) 的一个单独的驻留模块执行,该模块本身在同一命令行中指定的外部 FOR 循环内启动。如果在批处理文件内使用 FOR 循环来执行另一个(辅助)批处理文件,则该辅助批处理文件可能包含它自己的内部 FOR 循环。
- 注意
- 循环变量的名称必须选择得当,以防止与当前使用的任何其他变量发生冲突。
- 在括号内,正斜杠 ( / ) 被视为分隔符,但任何以正斜杠开头的单个项目将被附加到该斜杠并转换为大写(在早期的 DOS 版本中,斜杠的作用不同)。
- 尝试重定向来自 FOR 循环的所有消息只会影响该循环中的第一个操作。如果后续操作没有显式重定向,则它们将受默认设置控制。
- 当解释器 COMMAND.COM 从命令行显式启动以执行 FOR 循环时,循环变量必须以双百分号开头,就像在批处理文件中一样。
3.14 GOTO – 跳转到标签
[edit | edit source]GOTO 命令在批处理文件中执行跳转到一个标签,该标签必须在同一个批处理文件的任何一行中指定。带标签的行以冒号 ( : ) 开头,冒号后跟任意标签的名称。GOTO 命令后必须指定相同的名称。当标签名称很长时,只考虑前 8 个字符。同一个批处理文件不允许有同义标签。例如,如果批处理文件中的某一行有一个标签 `:L36`,那么使用以下命令跳转到该标签:
GOTO L36
GOTO 命令可以在同一行中由条件运算符 IF (3.15) 提前。在文章 9.03-02、9.09-02 中可以找到许多条件跳转和无条件跳转的示例。
- 注意
- GOTO 命令后的标签名称可以通过变量名称的替换来获取(例如 %VAR%)。
- 虚拟参数 (%1, %2..) 的值不能用作 GOTO 命令后的标签名称,但它可以在任何前面的字母之后构成该名称的一部分。
- GOTO 命令不影响 errorlevel,因此可以在跳转后继续执行 errorlevel 检查。
条件运算符允许执行三种类型的条件检查:存在检查、相等检查和 errorlevel 检查。
带有条件执行任何操作的命令行必须以条件运算符 IF 开头,后面跟着条件类型定义、条件规范以及在满足条件时应执行的命令的完整规范。
可以在一行中按顺序写入多个带有独立条件定义和规范的条件运算符,然后隐式地将逻辑运算符 AND 应用于独立条件检查的结果。文章 3.15-03、9.03-01、9.09-02 中展示了将多个条件检查组合在一行的示例。下面将详细介绍每种条件检查的命令行的特殊组成方式。
存在条件检查由 IF EXIST 命令执行,可以应用于文件、目录和逻辑设备。存在条件的反转——不存在条件检查——由 IF NOT EXIST 命令执行。以下是存在检查使用情况的两个示例:
IF EXIST C:\DOS\Format.com C:\DOS\Format.com A: /S IF NOT EXIST C:\DOS\Format.com ECHO Format.com isn't found!
其中
EXIST |
– | 一个保留字,用于定义检查类型并强制将后续元素解释为要搜索的对象的名称或掩码(可以带有路径)。 |
C:\DOS\Format.com – 要搜索的文件名的示例;前面有路径。此文件名将仅在指定的目录中搜索。当省略路径时,表示当前目录。 | ||
C:\DOS\Format.com A: /S – 如果满足前一个条件(检查返回 TRUE),则要启动的实用程序的示例。请注意,实用程序名称后面应该跟着所有必要的参数。当没有指定路径时,将从当前目录开始搜索实用程序,然后沿着存储在 PATH 变量值中的所有路径搜索。 | ||
NOT |
– | 一个保留字,表示检查任何条件类型返回的结果(TRUE 或 FALSE)的逻辑反转。 |
ECHO Format.com isn't found! – 另一个根据前一个条件执行的命令的示例(当未找到实用程序时)。 |
给定的示例可以在找到其正确位置时执行指定的实用程序(FORMAT.COM),或者在未找到此实用程序时显示一个可理解的消息。
逻辑设备的名称是保留字 (2.01-01),由 DOS 内核或驱动程序在加载过程中分配。通过对逻辑设备名称应用存在检查,可以确定是否加载了特定驱动程序。使用 /D 参数启动 MEM.EXE 实用程序 (6.17) 可以显示您计算机中的逻辑设备的完整列表。例如,EMM386.EXE (5.04-02) 驱动程序保留逻辑设备名称 EMMXXXX0。因此,可以使用以下行对该驱动程序进行加载检查:
IF NOT EXIST EMMXXXX0 ECHO The EMM driver isn't loaded!
当您使用带有通配符的文件掩码而不是要搜索的实用程序名称时,它将仅引用符合条件的文件,而不引用目录。当至少存在一个文件(或多个文件,3.09 中的示例)时,存在条件为 *.* 为真。为了检查目录是否存在,您应该在目录名称后面添加虚拟文件 NUL 的名称
IF EXIST C:\DOS\NUL ECHO The C:\DOS directory exists!
但是,显示的目录存在检查可能会在 CD-ROM 上失败,因为它们的文件系统 (ISO 9660) 有特殊性。
通常需要提供批处理文件的无停顿执行。存在检查仅在可访问的介质上提供无停顿执行:文件或目录可能不存在,但磁盘必须存在(必须插入)并且必须格式化为可供 MS-DOS 7 访问的文件系统(FAT12、FAT16、FAT32)或可通过安装的驱动程序访问。当不知道介质是否可访问时,仍然可以执行存在检查的无停顿执行,但需要采取特殊措施来防止关键错误处理程序调用 (8.02-84) 以及避免出现不希望的消息(9.03-02 中的示例)。
相等条件检查应用于两个用双等号 (==
) 分隔的词。由于比较先验已知的词没有意义,因此相等条件意味着使用别名,别名可以是虚拟参数或变量值 (2.03-03)。允许在要比较的词中使用通配符 (?
和 *
),但它们被解释为普通符号,不会扩展为通配符。与普通的 DOS 习惯做法相反,比较中的词中的大写和小写字母不视为相等。以下是在批处理文件中使用相等检查的两个示例:
IF %VAR%==%2 GOTO L23 IF NOT %VAR%==%2 GOTO HELP
其中
%VAR% |
– | 一个别名,将被环境变量 VAR 的值替换; |
%2 |
– | 一个别名(虚拟参数),将被批处理文件的第二个参数的值替换; |
GOTO L23 – 如果 %VAR%= =%2 条件满足,则要执行的命令; | ||
NOT |
– | 一个保留字,表示条件检查返回的结果(TRUE 或 FALSE)的逻辑反转; |
GOTO HELP – 如果 %VAR%= =%2 条件不满足,则要执行的命令。 |
当然,可以直接指定要比较的任何一个词,而无需使用别名。要比较的每个词都可以将一个或多个别名与直接指定的词部分组合。但是,不允许比较的词为空:这被视为语法错误。由于任何批处理文件都可以在没有参数的情况下执行,因此必须准备好在其虚拟参数(上面的示例中为 %2
或其他任何参数)为空的情况下执行。解决此问题的最简单方法是在等式左右两侧都添加一个特定的符号(例如,一个点):
IF %VAR%.==%2. GOTO L23 IF NOT %VAR%.==%2. GOTO HELP
这些相等检查与上一个示例中的检查相同,但不受别名为空值的影响。同样的原理也用于检查变量(或虚拟参数)的值是否为空:
IF .==%CASH%. ECHO The CASH variable has an empty value
当变量的值可能包含空格时,应格外小心。双等号右侧的词在其值中不允许有空格。如果变量 CASH(在上面的示例中)的值包含空格,它将被解释为语法错误。但是,双等号左侧的词允许在其内部有空格。当此词由多个用空格分隔的项组成时,只考虑第一个(最左边的)项。以下三个示例说明了这一点(三个示例都是有效的)
IF NOT A: B: C:.==. ECHO Compared items are not equal IF .A: B: C:==.A: ECHO Compared items (.A: and .A:) are equal IF . B: C:==. ECHO Compared items (dots) are equal too
在这三个示例中,B:
和 C:
项的存在都被忽略了。
当 DOS 中任何实用程序的执行即将结束时,它可能会留下 errorlevel 代码,即一个消息,传递给后续的算法。Errorlevel 指示已终止的执行是否成功,如果没有成功,则遇到了什么类型的障碍。Errorlevel 是 DOS 可交换数据区 (A.01-03 中的偏移量 14h) 中的 8 位二进制代码,但它以十进制数 (从 0 到 255) 表示(没有符号)。Errorlevel 0 表示成功终止,其他 errorlevel 值通常表示不同类型的错误,针对每个实用程序进行具体解释。
Errorlevel 条件由 ERRORLEVEL 关键字的存在来识别。它提供了一个机会来检查 errorlevel 代码是否等于或大于指定的十进制数,例如:
IF ERRORLEVEL 1 ECHO Execution has failed IF NOT ERRORLEVEL 1 ECHO Execution has terminated successfully
上面示例第一行中的检查对于从 1 到 255 的所有 errorlevel 值(即,对于所有可能的失败结果)返回 TRUE。第二行中的检查包含保留字 NOT,这就是它充当逻辑反转的原因,对于低于 1 的 errorlevel 返回 TRUE,即,对于单个值 0(表示成功终止)返回 TRUE。
当您需要对单一类型的错误结果执行单独的过程时,可以连接 errorlevel 检查。例如,假设在 errorlevel 为 15 的情况下,您需要执行到 ERROR15 标签的跳转。这可以通过以下命令行实现:
IF NOT ERRORLEVEL 16 IF ERRORLEVEL 15 GOTO ERROR15
上面行中的第一个检查对于从 0 到 15 的所有 errorlevel 返回 TRUE,第二个检查对于从 15 到 255 的所有 errorlevel 返回 TRUE。因此,errorlevel 15 是唯一允许执行后续 GOTO 命令的 errorlevel 值。
- 注意
- 一些实用程序使用非零 errorlevel 代码来指示正常(非错误)结果的不同情况。
- 所有内部命令 (3.01 - 3.34) 都不返回也不更改 errorlevel 代码。
- 允许以与上面显示的两个 errorlevel 检查相同的方式将多个存在检查、相等检查和 errorlevel 检查混合在一起。
3.16 LFNFOR – 长文件名显示模式
[edit | edit source]LFNFOR 是一个未公开的本地开关,可以设置为 ON (LFNFOR ON) 或 OFF (LFNFOR OFF)。在没有参数的情况下使用 LFNFOR 命令会显示该开关的状态。它的默认状态为 OFF。在“裸”MS-DOS 7 中,LFNFOR 的状态会被忽略,但在 Windows 操作系统下的 DOS 盒子中,将 LFNFOR 设置为 ON 会使 FOR 命令 (3.13) 对长文件名进行非截断处理,例如:
FOR %%Z in (*.*) do echo %%Z
当 LFNFOR 设置为 OFF 时,FOR 命令会将长文件名截断为 8 个字符,就像它在 MS-DOS 7 中一直做的那样。
3.17 LH – 加载到传统内存之外
[edit | edit source]LH 命令 (LH = Load High) 将驱动程序和 TSR 实用程序加载到具有 80386 或更高处理器的计算机的传统内存 640kb 边界之外。访问 640kb 边界之外的内存必须通过在 CONFIG.SYS 文件中使用命令 DOS=UMB
(4.08) 并加载内存管理器来提前启用:HIMEM.SYS 驱动程序 (5.04-01) 然后是 EMM386.EXE (5.04-02) 或 UMBPCI.SYS (5.04-04) 驱动程序。在这两种情况下,对由 LH 命令加载的 TSR 模块的访问都将通过地址空间的 UMB 区域 (640–1024kb) 进行。当 UMB 区域没有更多可用空间时,LH 命令不会发出错误消息,并继续将驱动程序和 TSR 实用程序加载到 640kb 以下的传统内存中。
LH 的作用类似于 INSTALLHIGH 命令 (4.16);主要区别在于 INSTALLHIGH 命令由 IO.SYS 加载器执行,不能参与内存优化过程 (5.04-03)。LH 命令由 COMMAND.COM 解释器从普通命令行执行,或(最好)从 AUTOEXEC.BAT 文件中的行执行。以下是一个 AUTOEXEC.BAT 文件中的一行的示例,其中 LH 命令用于加载 MSCDEX.EXE 驱动程序
LH /L:1,23680 \DOS\DRV\Mscdex.exe /D:CD1 /E /S /V /L:O /M:32
驱动程序名称之前是一个路径 (\DOS\DRV\
),它可以采用任何允许的形式 (2.02-01)。如果省略路径,将从当前目录以及 PATH 变量值 (2.02-02) 中指定的所有路径中搜索驱动程序。驱动程序名称后面的所有内容都不会被 LH 命令识别,而是作为特定参数传递给驱动程序。
在 LH 命令名称和要加载的软件规范之间,可能有一个可选的 /L
参数,它提供了一种方法来指出 USB 内存区域的特定部分,该部分应专门用于访问每个 TSR 模块 (另见 4.07)。在上面的示例中,该参数看起来像 /L:1,23680
,其中 /L:1
表示通过 UMB 区域的第一部分寻址,数字 23680 是 MSCDEX.EXE 驱动程序的 TSR 模块所需的空间大小(以字节为单位)。
/L
参数后的尺寸规范是可选的,但当指定尺寸时,LH 命令可以接受一个额外的参数 /S
,例如
LH /L:1,2160 /S \DOS\COM\Escape.com
/S
参数表示分配的 UMB 块应该被截断到指定的尺寸。这会导致地址空间的最高效使用,但不保证在尺寸规范不完全正确的情况下不会崩溃。不建议在内存优化实用程序 MEMMAKER.EXE (5.04-03) 执行的内存优化过程之外使用 /S
参数。在此过程中,/L
和 /S
参数以及精确的尺寸规范将自动插入所有包含 LH 命令的 AUTOEXEC.BAT 文件行中。
- 注意
- 如果通过 UMBPCI.SYS 驱动程序 (5.04-04) 打开了传统内存之外的访问,则 LH 命令将 TSR 模块加载到 UMB 内存区域 (640–1024kb) 中。但 EMM386.EXE 驱动程序 (5.04-02) 的作用不同:它调整处理器的地址转换表 (TLB),以便通过相同的地址空间 UMB 区域访问 1088kb 之外的内存。这就是为什么在后一种情况下,相同的 LH 命令实际上不会将 TSR 模块加载到 UMB 区域中,而是加载到 1088kb 之外的其他位置。
3.18 LOCK – 禁止并发访问
[edit | edit source]MS-DOS 7 控制着各种程序对磁盘访问的请求,以确保正确的访问顺序和有效的缓冲。需要直接访问磁盘的程序必须通过 INT 13\AH=45h 中断 (8.01-58) 与 MS-DOS 7 协调其操作。但有些程序没有这样做,例如,MS-DOS6.22 版本中用于恢复已删除文件的 UNDELETE.EXE 程序。为了允许此类程序执行其工作,MS-DOS 7 中的 COMMAND.COM 解释器提供了 LOCK 命令。它会赋予下一个将要启动的程序对请求的磁盘的独占访问权限。
LOCK 命令的参数是一个或多个要获得独占处理的磁盘的字母名称。在执行 LOCK 命令期间,系统会要求您从键盘上确认 (Y 或 N)。为了避免在批处理文件中进行确认操作,您必须预先准备一个响应,例如
ECHO Y | LOCK C: D:
显示的命令行的结果将是下一个将要启动的程序对磁盘 C: 和 D: 的独占无中断访问。当该程序终止时,应通过 UNLOCK 命令 (3.31) 关闭磁盘的锁定状态。由于直接访问操作可以嵌套,因此最多允许 256 个锁定级别。当然,每个参与的程序都必须由适当的 LOCK 和 UNLOCK 命令序列支持。
3.19 MD – 创建目录
[edit | edit source]MD 命令允许创建新的目录或子目录,例如
MD C:\DOS\ARC
其中
C:\DOS\ |
– | 一个指向现有目录的路径示例,新子目录应该在此处创建 |
ARC |
– | 要创建的新的唯一子目录名称的示例。此名称后面的反斜杠是不允许的。 |
新的唯一名称是必需的参数,但前面的路径是可选的。如果省略它,则将在当前磁盘的当前目录中创建新的(子)目录。
- 注意
- MKDIR 是相同 MD 命令的另一个有效名称。
3.20 PATH – 搜索路径(es)规范
[edit | edit source]PATH 命令定义了搜索没有指定路径且不在当前目录中的程序的默认路径。PATH 命令指定的路径构成了同义环境变量 PATH 的值。它的值也可以通过 SET 命令 (3.26) 定义。但存在一个重要的区别:与 SET 命令不同,PATH 命令会自动将指定路径中的所有字符转换为大写(否则搜索过程可能会出错)。PATH 命令必须后跟一个或多个现有路径,用分号分隔,例如
PATH C:\DOS\VC4;C:\DOS\MS7;C:\WINDOWS\COMMAND
PATH 命令将任意单词转换为大写字面的能力有时用于在进行区分大小写的相等性检查时避免歧义。
- 注意
- 在路径规范字符串中,每个分号分隔符两侧都不得有空格。
- 路径规范字符串的末尾不得有分号。
- 没有后续参数的 PATH 命令仅显示定义的路径,并保持不变。
- PATH ; 命令(仅后跟一个分号)会删除所有先前定义的路径。
- PATH 命令名称可以通过空格或等号 ( = ) 与后面的路径规范字符串分隔。
3.21 PAUSE – 临时停止
[edit | edit source]PAUSE 命令在批处理文件的一行中遇到时,会停止执行该批处理文件,并显示消息“按任意键继续...” 。此消息并不完全正确,因为 CTRL-C、CTRL-BREAK 和 ALT-03 键组合会终止执行,从而绕过批处理文件的所有剩余行(此操作不依赖于 BREAK 状态)。当 PAUSE 的消息不需要时,它可以被重定向。
PAUSE > NUL
PAUSE 命令后面可以紧跟一个注释字符串,就像 REM 命令一样。除非设置了 ECHO 标志(3.11),否则不会显示此注释。
当“CTTY NUL”命令(3.07)停止与控制台的默认通信时,PAUSE 命令必须进行显式输入重定向。
PAUSE < CON
在批处理文件中,将 03h 符号(显示为 ©,见 A.02-8)重定向到 PAUSE 命令提供了最短的方式来立即退出批处理文件的执行,没有任何暂停。
ECHO ©| PAUSE > NUL
可以使用 ALT-03 键将符号 03h 插入命令行,数字应在按住 ALT 键的同时通过数字键盘输入。但不要尝试使用前面的 REM 命令(3.24)禁用此行:只有 ECHO 命令会被禁用,重定向的符号不会被 PAUSE 命令接收,计算机将挂起。
3.22 PROMPT – 提示符规范
[edit | edit source]PROMPT 命令重新定义了同义环境变量 PROMPT 的值,该变量指定了 DOS 命令提示符的形式。通常,PROMPT 命令写在 AUTOEXEC.BAT 文件的一行中,但也可以从普通命令行中输入。PROMPT 名称后面应该跟着建议的提示符文本。在此文本中,以美元符号 ($) 开头的字符对以特殊方式解释,并被替换为其他无法直接写入提示符文本的数据。以下是字符对与替换数据之间对应关系的表格。
$Q | 等号 (=) |
$$ |
单个美元符号 ($) |
$T |
当前时间 |
$D |
当前日期 |
$P |
当前磁盘的字母名称和当前目录的路径 |
$V |
Windows 版本号 |
$N |
当前磁盘的字母名称 |
$G |
右箭头(或大于)符号 (>) |
$L |
左箭头(或小于)符号 (<) |
$B |
竖线(或管道)符号 (|) |
$H |
08h 代码“退格键”(A.02-8) |
$_ |
回车符 (0Dh) 和换行符 (0Ah) |
$E |
代码 1Bh “转义键”(A.02-8) |
不带参数的 PROMPT 命令会删除 PROMPT 变量,然后 DOS 提示符会显示当前磁盘的字母名称,后跟右箭头符号 (>),这与命令 PROMPT $N$G 后的提示符相同。默认情况下,MS-DOS 7 将另一个值(PROMPT $P$G
)分配给 PROMPT 变量,这对应于最常见的命令提示符形式:当前目录的完整路径,后跟右箭头符号。
提示符显示的数据可以写入文件,然后作为环境变量的值分配。考虑以下批处理文件行的示例。
prompt @echo off$_Set Ret$q$p C:\Command.com /c Ret.bat > Ret.bat Call Ret.bat
上面的示例中的第一行设置了提示符的复杂形式,第二行将此提示符写入新的批处理文件 RET.BAT。得到的 RET.BAT 文件的内容可能如下所示。
@echo off Set Ret=D:\BACKUP
请注意,提示符参数“Set Ret$q$p
”已转换为“Set Ret=D:\BACKUP
”,其中“D:\BACKUP
”是执行批处理行时当前磁盘的字母名称和实际当前路径的示例。如果使用 CALL 命令(3.02)执行 RET.BAT 文件,则实际完整路径将被写入环境变量 RET 的值中。之后,您可以删除 RET.BAT 文件,并在需要返回到先前磁盘和目录时使用 RET 变量。
%Ret%\ CD %Ret%
文章 9.01-03 展示了 PROMPT 命令用于获取当前磁盘字母名称的另一个示例。当前时间、日期和操作系统版本号可以以类似的方式写入环境变量。
3.23 RD – 删除目录
[edit | edit source]RD 命令(删除目录)可以删除目录,前提是满足以下条件。
- 要删除的目录为空;
- 该目录存在于可写磁盘上;
- 该目录不是磁盘的根目录;
- 该目录不是其磁盘上的当前目录,即使所寻址的磁盘不是当前磁盘。
以下是一个 RD 命令使用示例。
RD D:\TEMP\NOTES
其中
注释 |
– | 是要删除的目录的名称; |
D:\TEMP\ |
– | 是要删除的目录的路径示例。路径可以以任何允许的形式(2.02-01、2.02-03)指定,或者可以省略。如果省略了路径,则表示当前目录的子目录。 |
- 注意
- RMDIR 是相同 RD 命令的另一个有效名称。
3.24 REM – 注释行
[edit | edit source]REM 命令(REMark)强制 COMMAND.COM 解释器忽略同一命令行中后面的所有字符,直到遇到任何最近的重定向符号(2.04-02 - 2.04-05)或行末为止。REM 命令的主要任务是提供在批处理文件中插入注释行的机会。注释在一行中最多可以有 123 个字符。REM 命令用于注释,这些注释在正常执行批处理文件时不应显示,而应仅在使用 ECHO 标志(3.11)跟踪时显示。
REM 命令有时用于禁用批处理文件中的可执行行,但它不能禁用重定向。双冒号“::
”(2.04-01)更适合此目的。REM 的另一个任务是“空”命令,它被认为是有效的并被正式执行,但什么也不做(参见 6.25-03 中的 VCEDIT.EXT 示例)。
由于 REM 命令不会向 STDOUT 通道发送任何输出,因此重定向
REM > Anyfile.ext
用于创建指定名称的空文件。如果同义文件已存在,则将被覆盖并变为空。用零长度文件覆盖真实文件会擦除目录规范中其第一个簇的地址。因此,用零长度文件覆盖的文件无法通过 UNDELETE.EXE 或其他类似实用程序恢复。
- 注意
- REM 命令不应用于禁用具有中间重定向(2.04-05)的命令行。REM 命令只禁用此行中的第一个命令,其输出不会发送,并且命令行其余部分中的命令永远不会收到预期的数据。因此,计算机可能会挂起(文章 3.21 中的示例)。
- 在 Windows 操作系统的“DOS 窗口”中,不会执行空重定向,因此,不能使用 REM 命令创建零长度文件。
3.25 REN – 重命名文件
[edit | edit source]REN 命令(REName)可以重命名一个文件或多个文件,前提是它们的名称符合某个掩码。以下是一个使用 REM 命令重命名一个文件的示例。
REN C:\DOS\Notes.txt Notes.old
其中
C:\DOS\ |
– | 是要重命名的文件的路径示例;路径可以以任何允许的形式(2.02-01、2.02-03)指定,也可以省略。 |
Notes.txt – 要重命名的文件的当前名称。 | ||
Notes.old – 要重命名的相同文件的新的名称示例;新的名称必须在没有前缀路径的情况下指定,即使要重命名的文件存在于当前目录以外的任何其他位置。 |
只在第一个(旧)名称中指定通配符是允许的,但通常会导致错误:尝试在一个目录中创建多个同义文件。因此,建议在旧文件名和新文件名中相同的位置指定通配符,以便保留每个文件名的唯一特征。通配符隐藏的字符将不会改变。假设有一组文件 Part_01.txt - Part_12.txt 要重命名为 Chap_01.txt - Chap_12.txt。此操作通过一条命令执行。
REN Part_??.txt Chap_??.txt
- 注意
- 具有 H(隐藏)属性的目录和文件不能通过 REN 命令重命名。
- 重命名文件的属性保持不变。
3.26 SET – 为变量赋值
[edit | edit source]如果 SET 命令没有指定参数,它将显示当前环境的所有变量及其值。但是,如果 SET 命令的名称后面紧跟着任何单词,则该单词将被解释为应分配新值的 环境变量的名称,例如
SET TEMP=D:\Temp
其中
TEMP |
– | 是变量名称的示例; |
D:\Temp |
– | 是将分配给变量 TEMP 的值。值规范中禁止使用等号和重定向符号 (2.04-02 – 2.04-05)。 |
- 注意
- 等号右侧的任何空格,在有效字符之间、有效字符之前或之后(直到行尾标记),都将包含在变量的值中。
- 如果等号右侧的部分为空,则指定的变量将被删除(将不再存在)。
- SET 命令能够扩展环境空间,当它不足以容纳变量的新值时。
- 在批处理文件中,等号右侧的值可以包含其他变量名称的替换(例如,
%VAR%
)和虚拟参数 (2.03-03) 的替换。在定义新变量之前,所有这些别名将被替换为它们的值。 - CONFIG.SYS 文件行中同义词命令 SET (4.25) 由 IO.SYS 加载程序解释。后者不执行替换和重定向,但这样它就能够在变量的值中包含相应的符号。
3.27 SHIFT – 虚拟参数顺序移位
[edit | edit source]SHIFT 命令将批处理文件中虚拟参数 (2.03-03) 的数字顺序移位 -1(负一),因此以前的 %0 会丢失,以前的 %1 变成 %0,以前的 %2 变成 %1,等等。重要的是要注意,成为第 9 个的虚拟参数以前是第 10 个,无法访问。因此,SHIFT 命令为批处理文件提供了指定超过 9 个虚拟参数并按顺序访问它们的可能性,从一次迭代到下一次迭代移动它们的编号。DISK.BAT 文件第 29-38 行中的子例程展示了这种编号移位的示例,该文件位于文章 9.03-02 中。当移位的地址顺序到达参数序列的末尾时,最后一个虚拟参数将变为空,这将终止包含 SHIFT 命令的整个循环的执行。
3.28 TIME – 时间显示和重置
[edit | edit source]为了设置新时间,需要在命令行中 TIME 命令的名称后面指定该新时间,例如
TIME 11:39:23,24
其中连续的数字表示小时、分钟、秒和秒的百分之一。显示的时间规范中的分隔符是冒号和逗号,但这取决于 COUNTRY 命令 (4.05) 设置的国家/地区约定。
当没有指定时间时,将显示当前时间,然后会提示您通过键盘输入新时间。如果您不想更改时间,只需按 ENTER 键来响应提示即可。
为了将文本文件追加时间签名,应使用 TIME 命令,例如以下方式
ECHO= | TIME | Find.exe "Current" >> Anyfile.txt
这里第一个重定向 (ECHO= | TIME
) 自动响应显示的提示并启用不间断操作,第二个重定向 (TIME | Find.exe
) 排除不必要的输出行,第三个重定向 (>> Anyfile.txt
) 将时间签名追加到指定文件中。当然,执行重定向 (2.04-05) 和查找文件 (FIND.EXE 和要追加的文件) 的所有条件都应该满足。
3.29 TRUENAME – 路径和名称的规范形式
[edit | edit source]给定文件的相对规范,TRUENAME 将返回其完整名称及其绝对路径,此外,所有字母都将转换为大写,正斜杠将转换为反斜杠,星号 (2.01-03) 将转换为相应数量的问号,长名称将截断为 8 个字符,长后缀将转换为 3 个字符。
如果原始规范指出了由工具 ASSIGN.COM、JOIN.EXE 或 SUBST.EXE 编排的假路径,则 TRUENAME 命令将返回真实路径。当不使用后续规范时,TRUENAME 命令将返回当前目录的完整路径,就像 CD 命令 (3.03) 一样。
- 注意
- TRUENAME 命令不显示错误消息。
- 除非安装了 LAN 驱动程序,否则 TRUENAME 命令不能应用于网络路径。
- TRUENAME 命令的操作基于 INT 21\AH=60h (8.02-72)。
3.30 TYPE – 将文件读取到 STDOUT
[edit | edit source]TYPE 命令读取指定文件的内容,并将其逐行发送到 STDOUT 通道,该通道的默认终结点是 CON 设备(显示)。发送可以通过 CTRL-C 或 CTRL-BREAK 键击终止,或者通过按下 CTRL S 或 BREAK 键暂停,然后通过任何其他键击恢复。用法示例
TYPE C:\DOS\Notes.txt
其中
Notes.txt – 要显示的文件的名称示例;TYPE 命令不允许在名称中使用通配符。 | ||
C:\DOS\ |
– | 是 要显示的文件的路径示例;路径可以采用任何允许的格式 (2.02-01、2.02-03) 或省略。在后一种情况下,该文件隐含地存在于当前目录中。 |
TYPE 命令的输出可以重定向,例如,重定向到连接到 LPT1 端口的打印机
TYPE A:\Config.sys > PRN
TYPE 命令通常与 MORE.COM 查看器 (6.19) 一起使用,后者逐页显示长 STDOUT 消息。
3.31 UNLOCK – 并发访问权限
[edit | edit source]在已使用 LOCK 命令 (3.18) 授予磁盘直接访问权限的程序终止后,应使用 UNLOCK 命令恢复原始访问状态,该命令应用于相同的磁盘,例如
UNLOCK C:
实际上,UNLOCK 命令不允许多个并发访问,而是将禁止并发访问的嵌套禁止级别计数减少 1。因此,提供了对嵌套程序调用的适当处理。但是,如果原始禁止级别是 1,则 UNLOCK 命令将重新激活对磁盘访问请求的队列。这在多任务操作系统环境中很重要,例如在 Windows95/98 操作系统下的“DOS 窗口”中。如果磁盘最初没有被锁定,则 UNLOCK 命令不会执行任何操作。在任何情况下都不会显示消息。
3.32 VER – 操作系统版本显示
[edit | edit source]在 MS-DOS 7 和 MS-DOS 8 中,VER 命令 (VERsion) 显示相应的 WINDOWS 软件版本的版本号。提供 /R
参数后
VER /R
VER 命令将版本消息追加到关于 DOS 内核是否加载到高内存区域的备注。
3.33 VERIFY – 验证功能控制
[edit | edit source]VERIFY 命令在不带参数的情况下启动,指示验证功能的状态,该功能定义是否应该重新读取每个写入的文件并将其与原始文件进行比较。默认情况下,验证功能处于关闭状态,并且不执行验证。可以使用 VERIFY ON 或 VERIFY OFF 命令更改验证功能的状态(有关详细信息,请参阅 8.02-60 的注释 2)。
- 注意
- 现代硬盘的高可靠性使得验证变得不必要,它会导致时间损失和过度磁盘磨损。最好仅将 COPY 命令 (3.06) 的
/V
参数初始化为仅复制到软盘的文件。 - VERIFY 功能充当全局开关:当命令解释器的当前驻留模块完成其工作并且本地环境丢失时,它不会丢失其状态。
3.34 VOL – 磁盘标签和序列号
[edit | edit source]磁盘标签是由用户选择的最多 11 个字符的字符串。如果用户在格式化时未定义标签,则该磁盘将获得 NO NAME 标签。之后,可以使用 LABEL.EXE 实用程序 (6.16) 或某些 TSR shell(Norton Commander、Volkov Commander 等)更改磁盘标签。
序列号是一个 8 位十六进制标识符,在格式化过程中自动分配给磁盘。如果磁盘的生产技术采用磁接触复制格式化,则磁盘可能没有序列号。相反,在普通复制过程中,磁盘副本会从原始磁盘继承标签和序列号。
为了显示特定磁盘的标签和序列号,您需要在同一命令行中,在 VOL (= VOLume) 命令的名称后面指定其字母名称,例如
VOL A:
如果省略磁盘的字母名称,则将显示当前磁盘的卷标和序列号。