1. 如何在一个脚本的执行中调用另外一个脚本文件?
利用 Call 命令的两种用法来实现该功能:
l 调用另外一个脚本文件:
CALL [[<Drive>:]<Path>]<batch-file-name> [<parameters>]
注意 :
(1) 如果直接在脚本文件直接调用另外脚本,则子脚本正常或异常退出 (exit /b 语句 ) 都会导致父脚本的退出。直接写脚本或可执行文件相当于将子脚本的命令展开在父脚本中。
(2) Call 命令则是执行脚本,获得子脚本的退出代码,设置 errorlevel ,然后返回父脚本继续执行。
(3) Call 命令不会启动命令解释器的新的子进程,还是在执行父脚本的进程中执行子脚本, 因此子脚本中对环境变量的改变也会影响父脚本的执行。
(4) 另外 Call 命令还有隔离环境变量,在子脚本中定义的环境变量,即使是全局的环境变量,也不能影响父脚本的环境变量定义。而父脚本中的环境变量可以传递到子模块中。这样便于模块化构建脚本程序。
(5) Call 命令不影响当前目录。
l 从自身的某一行号开始执行:
CALL :<label> [<parameters>]
相当于使用自身脚本文件作为子脚本的递归调用。
2. 如何打开一个子进程来运行命令解释器?
使用 CMD 命令,执行命令解释器:
CMD [{/c|/k}] [/s] [/q] [/d] [{/a|/u}] [/t:<f><g>] [/e:{on|off}] [/f:{on|off}] [/v:{on|off}] [<string>]
其中的选项(大小写不敏感)解释如下:
(1) [{/c|/k}] [/s]: /k 执行完 <string> 命令后不退出命令解释器,等待用户输入; /c 执行完 <stirng> 命令立即返回;
/s 修饰以上两者:
如果指定了 /C 或 /K ,命令选项后的命令行其余部分将作为命令行处理;在这种情况下,会使用下列逻辑处理引号字符 ("):
1. 如果符合下列所有条件,那么在命令行上的引号字符将被保留 :
- 不带 /S 命令选项 - 整整两个引号字符
- 在两个引号字符之间没有特殊字符,特殊字符为下列中的一个 : & < > [ ] { } ^ = ; ! ' + , ` ~ [white space]
- 在两个引号字符之间有至少一个空白字符
- 在两个引号字符之间有至少一个可执行文件的名称。
2. 否则,老办法是,看第一个字符是否是一个引号字符,如果是,舍去开头的字符并删除命令行上的最后一个引号字符,保留最后一个引号字符之后的文字。
(2) /q: 关闭回显,默认打开
(3) /d: 关闭在执行命令前自动执行的脚本命令,默认执行,这些命令在注册表中的一下路径指定:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun\REG_SZ
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun \REG_EXPAND_SZ
(4) [{/a|/u}] : 以 ascii 码或 unicode 标准向管道或者文件输出
(5) [/t:<f><g>]: 指定前景色和背景色,默认黑地白字:
0 | Black |
1 | Blue |
2 | Green |
3 | Aqua |
4 | Red |
5 | Purple |
6 | Yellow |
7 | White |
8 | Gray |
9 | Light blue |
A | Light green |
B | Light aqua |
C | Light red |
D | Light purple |
E | Light yellow |
F | Bright white |
(6) [/e:{on|off}] : 打开或关闭命令扩展, 默认打开
(7) [/f:{on|off}] : 打开或关闭文件或目录名自动完成,自动完成的键设置在注册表中:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar\REG_DWORD
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar\REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar\REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar\REG_DWORD
键值格式为: 0xNN, NN 是十六进制的 ASCII 码。
(8) <string>: 命令字符串
注意:
打开一个子 shell 进程,返回时不影响父 shell 的环境变量
外部的调用 shell 传递进来的环境变量(无论在父进程中是局部变量还是全局变量)
在子 shell 中都是全局初始化变量。
[ZT] 命令的延迟扩展:
From: 中国的 DOS 联盟
在许多可见的官方文档中,均将使用一对百分号闭合环境变量以完成对其值的替换行为称之为 “ 扩展( expansion ) ” ,这其实是一个第一方的概念,是从命令解释器的角度进行称谓的,而从我们使用者的角度来看,则可以将它看作是引用( Reference )、调用( Call )或者获取( Get )。
而命令解释器是扩展环境变量的行为大致如下:首先读取命令行的一条完整语句,在进行一些先期的预处理之后,命令被解释执行之前,会对其中用百分号闭合的字符串进行匹配,如果在环境空间中找到了与字符串相匹配的环境变量,则用其值替换掉原字符串及百分号本身,如果未得到匹配,则用一个空串替换,这个过程就是环境变量的 “ 扩展 ” ,它仍然属于命令行的预处理范畴。
而一条 “ 完整的语句 ” ,在 NT 的命令解释器 CMD 中被解释为 “for if else” 等含有语句块的语句和用 “& | && ||” 等连接起来的复合语句。
因此,当 CMD 读取 for 语句时,其后用一对圆扩号闭合的所有语句将一同读取,并完成必要的预处理工作,这其中就包括环境变量的扩展,所以在 for 中的所有语句执行之前,所有的环境变量都已经被替换为 for 之前所设定的值,从而成为一个字符串常量,而不再是变量。无论在 for 中将那些环境变量如何修改,真正受到影响的只是环境变量空间,而非 for 语句内部。
而为了能够在 for 语句内部感知环境变量的动态变化, CMD 设计了延迟的环境变量扩展特性,也就是说,当 CMD 读取了一条完整的语句之后,它不会立即执行变量的扩展行为,而会在某个单条语句执行之前再进行扩展,也就是说,这个扩展行为被 “ 延迟 ” 了。
延迟环境变量扩展特性在 CMD 中缺省是关闭的,开启它的方法目前有两个:一是 CMD /v:on ,它会打开一个新的命令行外壳,在使用 exit 退出这个外壳之前,扩展特性始终有效,常用于命令行环境中;二是 setlocal EnableDelayedExpansion ,它会使环境变量的修改限制到局部空间中,在 endlocal 之后,扩展特性和之前对环境变量的修改将一同消失,常用于批处理语句中。
3. 如何调用子进程来执行其他程序(当然也包括 CMD.exe )或者通过文件关联来打开文件?
Start 命令可以用来执行该操作,利用文件关联来启动相应的程序打开文件:
START [/d<path>] [/separate|/shared]
[“<title>”] [/i] [/b] [{/min|/max}] [{/low|/high|/normal|/abovenormal|/belownormal|/realtime}]
[/wait] [/b] <command>
其中选项为:
(1) <title>: 新建窗口的题目
(2) <path>: 初始路径
(3) [{/min|/max}] : 启动窗口大小
(4) [{/low|/high|/normal|/abovenormal|/belownormal|/realtime}]: 制定运行级别
(5) /wait: 父进程等待子进程执行结束,如果子进程启动的是 GUI 程序,同样等待。
(6) [/separate|/shared]: 在共享或独立空间运行 16 位程序
(7) <command>: 要执行的命令行,如果是 CMD 将被 CMDSPEC 环境变量替换,防止从当前目录执行 CMD
(8) /i: 新环境是传递 cmd 的原始环境,而不是当前环境
(9) /b: 见下面说明
说明:
Start 命令打开一个新窗口并启动子进程执行命令解释器,在命令解释器中执行 <command> 。对于非 GUI 程序,执行完毕后不返回主程序,而是等待用户继续输入,直到 exit 。对于 GUI 程序,启动界面后立即返回,并关闭解释器窗口(和脚本中的行为不同,在脚本中是等待 GUI 程序退出,继续执行后续命令)。如果父进程在等待,则直到该 GUI 程序退出,父进程才返回(或者父进程被 Ctrl+C 中止等待,但不影响 GUI 程序的执行)。
但是如果指定 /b 选项, start 并不启动一个新的窗口和进程,而是在当前窗口执行。这时如果没有指定 /wait 选项,只有通过 Ctrl+Break 方法中止该程序,而 Ctrl+C 由父进程解释器处理,因而不能中止该程序,但解释器启动的程序可以得到 Ctrl+C 的输入来自行处理该事件。
Start 命令定义了一些扩展名作为搜索可执行程序的范围,这些扩展名在 PATHEXT 变量中被定义,一般是:
.COM;.EXE;.BAT;.CMD;
如果给出的是文件名,则利用文件关联来打开;如果是目录,则用 explorer.exe 打开。
Start 命令是在系统 ” 启动 ” 对话框中被用来启动应用程序。
4. 如何退出脚本 ?
可以利用 EXIT 来退出脚本或命令解释器 :
EXIT [/b] [<n>]
/b 选项打开,表示如果是在执行脚本程序,则退出脚本程序,否则退出命令解释器。如果没有指定 /b, 则总是退出命令解释器。
<n> 是退出代码,如果只是退出脚本程序,命令解释器设置 ERRORLEVEL 为 <n>; 如果退出命令解释器,则进程的退出代码被设置为 <n> 。 <n> 默认值是 0 ,当脚本执行到末尾,其退出代码也是 0 。
5. 如何理解 Error level ?
Error level 用来表示命令或程序执行结果的状态, 0 表示正常退出,其它值表示异常退出,一般异常值越大表示错误越严重,但也可用来表示错误的类型。
Error level 可以通过设置环境变量 ERRORLEVEL 来设定:
SET ERRORLEVEL=<n>
也可通过在脚本退出时设定:
EXIT /b <n>
当命令解释器执行一个可执行程序或内部命令时,获取该进程的退出代码作为 Error level 。
在执行 CHOICE 命令时也会改变 errorlevel 的值。
注意: Errorlevel 是整数值(正负均可)。通过设置环境变量,虽然可以将 ERRORLEVEL 设置为非整数值字符串,在使用的时候会自动转化为 0 。虽然在 EXIT 退出时也可以用字符串作返回值,但 errorlevel 会被命令解释器自动转化为 0 。
6. 如何在局部范围内指定命令扩展和变量扩展?
SETLOCAL
[{enableextension | disableextensions}] [{enabledelayedexpansion | disabledelayedexpansion}]
该命令可以嵌套,如果设置成功其中任意一个选项, ERRORLEVEL 变量被设置为 0 ,否则为 1 ,可以用这个来判断命令解释器是否具有上述开关功能。
联系客服