1. exit

exit命令用于退出当前的批处理脚本,并返回一个退出代码ExitCode(即返回值)。退出代码通常是一个整数,用于指示脚本执行的状态,例如成功(0)或失败(非零值)。

exit命令的语法为:

1
exit [/b] [exitCode]

其中 /b 选项表示仅退出当前批处理脚本的执行,而不会影响调用脚本的父进程。如果不使用 /b 选项,则 exit 命令会终止当前整个的命令处理器进程(CMD.EXE),并返回退出代码给调用者。

exitCode 是一个可选参数,用于指定退出代码。如果未指定退出代码,则默认返回上一个命令的退出代码。

2. 变量延迟扩展

SETLOCAL ENABLEDELAYEDEXPANSION的作用是设置本地变量延迟扩展。

CMD在执行命令前会对脚本进行预处理,在这个过程中,如果有类似%value%这样的变量就会对其进行识别,并且查找这个变量对应的值,从而用该值替换掉变量,这个替换值的过程,就叫变量扩展,这个类似于C/C++中的宏。

请看下面示例:

1
2
3
@echo off
set a=4
set a=5 & echo %a%

结果:4

为什么输出是4而不是5呢?

原因是批处理是按行读取命令的(另外例如for命令等,其后用一对圆括号闭合的所有语句也当作一行),在执行之前要完成必要的预处理工作,这其中就包括对该行命令中的变量赋值。上例中,批处理在运行到set a=5 & echo %a%之前,先把这一整句读取并做了预处理(对变量a赋了值),此时%a%当然就是4。

明白这个道理之后,我们将上例修改为如下方式,就可以输出结果5。

1
2
3
4
@echo off
set a=4
set a=5
echo %a%

为了能够让批处理感知变量的动态变化,批处理设计了变量延迟,即在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在单条语句执行之前再进行赋值,也就是说“延迟”了对变量的赋值。

1
2
3
4
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set a=4
set a=5 & echo !a!

结果:5

由于启动了变量延迟,得到了输出结果5。

变量延迟的启动语句是SETLOCAL ENABLEDELAYEDEXPANSION,并且变量要用一对叹号括起来,否则就没有变量延迟的效果。

3. 调用npm命令无法返回原批处理

需要使用call命令,如:

1
call npm install

具体原因参考:批处理运行外部程序

可以使用%errorlevel%获取命令的执行结果(通常0表示成功),如:

1
2
3
4
5
6
call npm run build-release
if %errorlevel% NEQ 0 goto ERROR


:ERROR
echo Compile Failed

4. 切换脚本的当前目录

有些命令依赖批处理程序的当前目录,如npm、yarn这样的命令。假如项目位于D:\A\B路径,使用批处理(文件位于D:\build.bat)进行自动构建:

1
2
3
@echo off
cd D:\A\B
call npm run build

运行上面批处理,构建会失败,通常会提示诸如“D:\package.json不存在”的错误,原因是npm命令是批处理程序的当前目录查找package.json文件的,批处理程序的当前目录默认为批处理文件所在的目录,即D:\D:\package.json不存在,因此构建失败。

可以使用为cd命令指定/d参数来切换批处理程序的当前目录,上面示例可以修改为:

1
2
3
@echo off
cd /d D:\A\B
call npm run build

5. 批处理命令换行

当批处理命令过长,如果都写在一行不便于阅读,可以使用^符号进行分割。

1
2
3
4
5
6
call "%qt_src_folder%\configure.bat" -silent -debug-and-release -force-debug-info -strip ^
-platform win32-msvc -static -static-runtime -no-opengl -no-dbus -no-icu ^
-nomake examples -nomake tests -skip qtwebengine -skip qtlocation ^
-qt-harfbuzz -qt-freetype -qt-zlib -qt-doubleconversion ^
-mp -optimize-size -ltcg -no-pch ^
OPENSSL_LIBS="-lUser32 -lAdvapi32 -lGdi32 -lWS2_32 -lCRYPT32 -llibcrypto32 -llibssl32"

6. ECHO 处于关闭状态

遇到“ECHO 处于关闭状态”提示,通常是因为输出变量为空导致。

此时需要注意如下情况:

  • 批处理变量左右不能有空格。如果有空格,空格会被当成变量名,如set a =1,变量名实际为a
  • 开启变量延迟扩展后,引用变量需要使用两个!的方式,如!str_a!

7. 显示选择项提示用户选择

使用CHOICE命令可以提供用户在指定的选项中选择一项,并使用%ERRORLEVEL%获取选择的值。

CHOICE命令语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]

描述:
该工具允许用户从选择列表选择一个项目并返回所选项目的索引。

参数列表:
/C choices 指定要创建的选项列表。默认列表是 "YN"。

/N 在提示符中隐藏选项列表。提示前面的消息得到显示,
选项依旧处于启用状态。

/CS 允许选择分大小写的选项。在默认情况下,这个工具
是不分大小写的。

/T timeout 做出默认选择之前,暂停的秒数。可接受的值是从 0
到 9999。如果指定了 0,就不会有暂停,默认选项
会得到选择。

/D choice 在 nnnn 秒之后指定默认选项。字符必须在用 /C 选
项指定的一组选择中; 同时,必须用 /T 指定 nnnn。

/M text 指定提示之前要显示的消息。如果没有指定,工具只
显示提示。

/? 显示此帮助消息。

注意:
ERRORLEVEL 环境变量被设置为从选择集选择的键索引。列出的第一个选择返回 1,第二个选择返回 2,等等。
如果用户按的键不是有效的选择,该工具会发出警告响声。如果该工具检测到错误状态,它会返回 255 的ERRORLEVEL 值。
如果用户按 Ctrl+Break 或 Ctrl+C 键,该工具会返回 0的 ERRORLEVEL 值。
在一个批程序中使用 ERRORLEVEL 参数时,将参数降序排列。

如:

1
CHOICE /C YNC /M "确认请按 Y,否请按 N,或者取消请按 C。"