Windows 批处理脚本是 Windows 命令提示符中的一种基础自动化方式。它通常保存为 .bat 或 .cmd 文件,可以把多条 cmd 命令按顺序组织起来,一次性执行。
在日常使用中,批处理脚本可以用于批量复制文件、创建目录、启动程序、检查环境、备份文件、执行构建命令、清理临时文件等任务。它不适合复杂系统管理和大型自动化工程,但非常适合处理简单、稳定、重复的命令行任务。
学习批处理脚本之前,最好先熟悉一些常用命令,例如 cd、dir、copy、move、del、rmdir、findstr、where、robocopy、tasklist、taskkill 等。批处理脚本的本质,就是把这些命令按照一定逻辑组合起来。
一、什么是批处理脚本
批处理脚本通常指 Windows 中以 .bat 或 .cmd 结尾的脚本文件。
例如:
clean.cmd双击这些文件,Windows 通常会调用 cmd.exe 执行其中的命令。也可以在命令提示符中直接输入脚本文件名运行:
hello.bat或者:
backup.cmd.bat 和 .cmd 在现代 Windows 中大多数情况下用法接近,二者都由 cmd.exe 解释执行。
批处理脚本适合解决的问题包括:
• 重复执行多条命令
• 批量处理一组文件
• 自动创建目录结构
• 自动复制、移动、删除文件
• 检查某个程序是否存在
• 调用其他命令行工具
• 为开发项目提供简单启动脚本
需要注意的是,批处理脚本主要面向传统 cmd 命令环境。对于复杂对象处理、系统管理、跨平台脚本和现代自动化任务,PowerShell 通常更合适。
二、创建第一个批处理脚本
可以先创建一个最简单的批处理文件。
新建文件 hello.bat,写入以下内容:
pause保存后双击运行,或者在命令提示符中进入该文件所在目录,然后执行:
hello.bat这三行代码分别表示:
@echo off:关闭命令本身的回显,让输出更清爽。
echo Hello Windows:在窗口中输出文本。
pause:暂停脚本,等待用户按任意键继续。
如果不写 pause,双击运行时窗口可能会一闪而过,因为脚本执行完后命令窗口会自动关闭。
三、批处理脚本的执行流程
批处理脚本默认按照从上到下的顺序逐行执行。
例如:
pause执行结果会依次显示三行内容。
批处理脚本中的每一行通常就是一条 cmd 命令。也就是说,下面这些在命令提示符中可以直接执行的命令,也可以写入批处理文件:
pause这段脚本会切换到当前用户桌面目录,然后列出桌面中的文件和文件夹。
批处理脚本的执行过程可以理解为:
直到文件结束后面要学习的变量、参数、条件判断和循环,都是在这个基本执行流程上增加控制能力。
四、注释与输出
批处理脚本中可以使用 rem 添加注释。
pauserem 后面的内容不会作为命令执行,主要用于解释脚本逻辑。
有些脚本中也会看到 :: 形式的注释:
echo Hello这种写法很常见,但在复杂括号代码块中可能出现特殊问题。入门阶段更推荐使用 rem。
输出文本使用 echo:
pause如果要输出空行,可以写:
echo.例如:
pauseecho 也可以用于查看当前是否开启命令回显:
echo不过在大多数脚本中,常见写法仍然是:
@echo off这样可以让脚本只显示需要显示的内容,而不是把每条命令本身也显示出来。
五、变量的基本用法
批处理脚本可以使用 set 定义变量。
基本语法是:
set 变量名=变量值示例:
pause运行结果是:
Hello Windows在批处理脚本中,读取变量时通常使用:
%变量名%例如:
pause变量赋值时要注意,等号两边不要随意添加空格。
错误写法:
set name = Windows这会把变量名理解为 name ,变量值理解为 Windows,从而引发难以发现的问题。
更稳妥的写法是:
set "name=Windows"例如:
pause这种写法可以避免不小心把多余空格写入变量值中。建议在正式脚本中优先使用这种形式。
六、使用系统环境变量
Windows 中有很多常用环境变量,批处理脚本可以直接读取。
例如:
pause常见环境变量包括:
%USERPROFILE%:当前用户目录
%USERNAME%:当前用户名
%SystemRoot%:Windows 系统目录
%TEMP%:当前用户临时目录
%PATH%:命令搜索路径
%CD%:当前工作目录
这些变量可以让脚本更通用。比如,不要把桌面路径写死为:
C:\Users\用户名\Desktop更推荐写成:
%USERPROFILE%\Desktop示例:
pause这样脚本在不同用户的电脑上运行时,更不容易因为用户名不同而失效。
七、接收命令行参数
批处理脚本可以接收外部传入的参数。
新建文件 args.bat,内容如下:
pause在命令提示符中执行:
args.bat apple banana输出结果类似:
所有参数:apple banana常用参数含义如下:
%0:当前脚本自身
%1:第一个参数
%2:第二个参数
%3:第三个参数
%*:所有参数
%~1:去掉第一个参数外层引号后的内容,常用于处理带空格的路径参数
echo 去掉外层引号:%~1如果参数中包含空格,需要加引号:
args.bat "C:\My Folder" backup在脚本中使用参数时,也建议加引号:
pause加引号的原因是:当参数为空或包含空格时,可以减少语法错误。
八、路径与脚本所在目录
批处理脚本中最容易混淆的概念之一,是“当前工作目录”和“脚本所在目录”。
当前工作目录是脚本运行时所在的目录。脚本所在目录是 .bat 或 .cmd 文件实际保存的位置。二者不一定相同。
批处理脚本中常用 %~dp0 表示当前批处理文件所在的驱动器和路径。
例如:
pause如果希望脚本无论从哪里启动,都先切换到脚本所在目录,可以写:
pause这里的 cd /d 很重要。它不仅可以切换目录,还可以切换驱动器。
例如,脚本在 D 盘,但当前命令窗口在 C 盘时:
cd "%~dp0"不一定能完成驱动器切换,而:
cd /d "%~dp0"更稳妥。
%~dp0 非常适合用于访问脚本旁边的文件。例如,假设目录结构如下:
└─ app.exe可以在 run.bat 中写:
pause这样,即使用户从其他目录启动脚本,也能正确找到 config.txt 和 tools\app.exe。
九、条件判断
批处理脚本可以使用 if 进行条件判断。
1、判断文件是否存在
pauseif exist 可以判断文件或目录是否存在。
判断目录也可以这样写:
)路径中有空格时,必须加引号。
if exist 既可以判断文件,也可以判断目录。如果专门判断目录,路径末尾也可以写成 "C:\temp\",可读性更强。
2、判断参数是否为空
pause执行:
check.bat会提示没有提供参数。
执行:
check.bat README.txt会显示传入的文件名。
3、判断字符串是否相等
pause这类脚本可以用来制作简单的命令入口。
例如:
tool.bat clean对应脚本可以写成:
pause这里的 else if 可以理解为 else 后面继续嵌套一个 if。cmd 中没有像某些编程语言那样专门的 elseif 关键字。
这里的 ^| 表示输出普通的竖线字符 |,避免被 cmd 当成管道符解释。
十、错误判断与 errorlevel
很多命令执行后会返回一个退出码。批处理脚本可以通过 errorlevel 判断上一条命令是否执行成功。
一般情况下,0 表示成功,非 0 表示失败或异常。
示例:检查系统中是否能找到 Python。
pause这里涉及四个关键点:
where python:查找 python 命令所在路径。
> nul:丢弃标准输出。
2>&1:把错误输出重定向到标准输出当前指向的位置。
if errorlevel 1:判断上一条命令返回码是否大于等于 1。
需要注意,if errorlevel 1 的含义是“错误级别大于或等于 1”,不是“错误级别等于 1”。
更明确的写法是使用 %errorlevel%:
pause不过在 if、for 等括号代码块中,%errorlevel% 可能受到变量提前展开的影响;需要动态读取时,可结合延迟变量扩展理解。
还要注意,不同命令的退出码含义不完全一样。
例如 robocopy 的返回码比较特殊,非 0 不一定表示失败。因此,在用批处理脚本判断某个命令是否成功时,最好查清楚该命令的返回码规则。
十一、使用 && 和 ||
批处理脚本可以使用 && 和 || 根据上一条命令是否成功来决定后续操作。
&& 表示上一条命令成功后执行:
mkdir backup && echo backup 目录创建成功|| 表示上一条命令失败后执行:
dir not_exist || echo 目录不存在也可以组合使用:
pause这种写法适合简单判断。如果 && 后面的命令本身执行失败,也可能触发 || 后面的分支。因此,复杂逻辑中更推荐使用 if errorlevel。
十二、循环处理文件
批处理脚本中常用 for 处理一组文件。
例如,列出当前目录下所有 .txt 文件:
pause这里要特别注意:在批处理文件中,循环变量写成 %%f。在命令提示符中直接执行时,循环变量写成 %f。
也就是说,在 .bat 文件中写:
for %%f in (*.txt) do echo %%f在 cmd 窗口中直接写:
for %f in (*.txt) do echo %f二者只差一个 %,但经常让初学者出错。
1、批量复制文件
pause这段脚本会把当前目录下所有 .txt 文件复制到 backup 文件夹。
2、批量显示文件名
pause3、递归处理文件
如果要处理当前目录及子目录中的文件,可以使用 /r:
pausefor /r 会递归遍历子目录。处理删除、覆盖、移动等高风险操作时,不建议一开始就直接执行。可以先用 echo 打印结果,确认范围正确后再改成真正的操作命令。
十三、数字计算与 set /a
批处理脚本可以使用 set /a 进行简单整数计算。
例如:
pause输出结果是:
3可以用于计数:
pause不过,在循环或括号代码块中直接使用 %count% 可能遇到变量展开问题。例如:
pause这段脚本可能不会得到预期结果,因为 %count% 在代码块执行前就已经被展开。要解决这个问题,需要使用延迟变量扩展。
十四、延迟变量扩展
延迟变量扩展用于解决括号代码块中变量更新后无法及时读取的问题。
基本写法是:
setlocal enabledelayedexpansion然后使用 !变量名! 读取变量。
示例:
pause这里使用 !count!,可以在每次循环中读取更新后的变量值。
这一点是批处理脚本中非常重要的概念。可以简单理解为:
%变量名%:在代码块执行前展开。
!变量名!:在代码块执行过程中动态展开。
常见代码块包括:
if (...) else (...)
for (...) do (...)
只要在这些括号中修改变量并立即读取变量,就经常需要使用延迟变量扩展。
十五、setlocal 与 endlocal
setlocal 用于开启局部环境。脚本中对环境变量所做的修改,会限制在当前脚本局部范围内。遇到 endlocal 或脚本结束时,环境会恢复到之前状态。
示例:
pause在实际脚本中,经常会在开头写:
setlocal如果需要延迟变量扩展,则写:
setlocal enabledelayedexpansion脚本结尾可以写:
endlocal也可以省略,因为脚本结束时通常会自动结束局部环境。不过在结构较清晰的脚本中,显式写出 endlocal 更容易阅读。
十六、调用其他脚本与 call
一个批处理脚本可以调用另一个批处理脚本。
假设有两个文件:
sub.batsub.bat 内容如下:
echo 这里是 sub.batmain.bat 内容如下:
pause这里要使用 call。如果在批处理文件中直接写:
sub.bat可能会导致控制流程直接转到 sub.bat,执行完后不再回到原脚本继续执行。使用 call sub.bat 可以在子脚本执行完成后返回父脚本。
call 也可以传递参数:
call sub.bat apple banana在 sub.bat 中可以用 %1、%2 读取这些参数。
十七、使用标签与 goto
批处理脚本可以使用标签和 goto 跳转。
标签以冒号开头:
:label示例:
pausegoto 可以实现简单的流程跳转,但过度使用会让脚本结构变得混乱。较简单的分支可以使用 if,较复杂的脚本再使用标签组织流程。
常见做法是把脚本末尾作为统一出口:
pause或者:
exit /bexit /b 表示退出当前批处理脚本,而不是关闭整个 cmd 窗口。
或者:
exit /b 1exit /b 0 通常表示脚本正常结束;exit /b 1 通常表示脚本异常结束。这个返回码可以被调用方或后续脚本读取。
十八、输入与交互
批处理脚本可以使用 set /p 接收用户输入。
示例:
pause也可以用于确认操作:
pause其中 /i 表示忽略大小写。因此 yes、YES、Yes 都可以匹配。
对于删除、覆盖、镜像同步等高风险操作,建议增加确认步骤。
例如:
pause这种确认机制虽然简单,但能避免很多误操作。
十九、重定向与日志文件
批处理脚本经常需要把执行结果写入日志文件。
1、覆盖写入
dir > log.txt> 会覆盖原文件内容。
2、追加写入
dir >> log.txt>> 会追加到文件末尾,不会覆盖原内容。
3、保存错误信息
dir not_exist 2> error.txt其中 2> 表示重定向错误输出。
4、同时保存正常输出和错误输出
dir not_exist > result.txt 2>&1在批处理脚本中,可以这样记录日志:
pause这里需要注意:
> 会覆盖文件。
>> 会追加文件。
2>&1 用于把错误输出重定向到标准输出当前指向的位置。
二十、常见自动化示例
下面给出几个比较实用的批处理脚本示例。它们都保持简单结构,便于理解和修改。
1、创建项目目录结构
pause执行:
create_project.bat demo会创建:
└─ tests2、备份指定目录
pause这个脚本使用 robocopy 复制目录。参数含义:
/e:复制所有子目录,包括空目录。
/r:3:失败后重试 3 次。
/w:5:每次重试前等待 5 秒。
这里没有使用 /mir,因为 /mir 会删除目标目录中源目录没有的文件,风险较高。
3、检查常用开发工具是否可用
pause这个脚本适合检查开发环境是否配置完成。
4、批量整理日志文件
pause这段脚本会把当前目录下的 .log 文件复制到 logs_backup 文件夹。
5、清理临时文件
pause这个脚本增加了确认步骤,避免误删文件。
二十一、中文编码与乱码问题
批处理脚本中如果包含中文,可能会遇到乱码问题。常见原因是脚本文件编码与当前命令行代码页不一致。
可以在命令提示符中查看当前代码页:
chcp有时可以在脚本中切换到 UTF-8:
pausechcp 65001 只改变当前命令行代码页,并不等于自动改变脚本文件的保存编码。脚本文件本身仍需要用合适的编码保存。
不过,编码问题与 Windows 版本、终端环境、编辑器保存格式有关。为了减少乱码,建议:
使用支持明确选择编码的编辑器保存脚本。
脚本中尽量避免过多中文路径。
中文提示可以保留,但命令、路径、变量名尽量使用英文。
在需要 UTF-8 的脚本中,可尝试使用 chcp 65001。
变量名建议使用英文:
set "target=D:\backup"不建议写成:
set "源目录=C:\project"虽然某些情况下可以运行,但兼容性和可维护性较差。
二十二、容易出错的地方
1、路径中有空格必须加引号
错误写法:
cd C:\Program Files正确写法:
cd /d "C:\Program Files"复制文件时也一样:
copy "C:\My Folder\a.txt" "D:\Backup Folder\"2、变量赋值时不要随意加空格
推荐写法:
set "name=Windows"不推荐:
set name = Windows3、批处理文件中的 for 变量要写两个百分号
批处理文件中:
for %%f in (*.txt) do echo %%f命令行中直接执行:
for %f in (*.txt) do echo %f这点非常容易混淆。
4、当前目录不一定等于脚本所在目录
脚本中需要访问自身旁边的文件时,建议先写:
cd /d "%~dp0"5、在括号代码块中修改变量时,注意延迟变量扩展
需要在循环中动态读取变量时,使用:
setlocal enabledelayedexpansion并用:
!变量名!读取变量。
6、删除和镜像同步命令要谨慎
高风险命令包括:
robocopy source target /mir执行前应先用 echo、dir 或确认提示检查目标路径。
7、不要把复杂系统管理都写成批处理
批处理脚本适合简单自动化。涉及复杂系统配置、对象处理、远程管理、复杂错误处理时,PowerShell 通常更适合。
二十三、批处理脚本的使用建议
编写批处理脚本时,可以遵循以下原则。
1、先手动执行,再写入脚本
先在命令提示符中确认命令能正常运行,再把命令写入 .bat 或 .cmd 文件。
2、先 echo 检查,再真正执行
批量删除、移动、复制前,可以先写:
)确认输出无误后,再改成:
)3、路径统一加引号
即使路径当前没有空格,也建议写成:
"%target%"这样脚本更稳。
4、重要操作前增加确认
例如:
set /p answer=确认继续请输入 YES:删除、覆盖、同步前尤其应该这样做。
5、脚本开头写清楚用途
可以使用注释说明脚本用途:
rem 用法:backup.bat脚本越容易被别人理解,后续维护成本越低。
小结
批处理脚本把多条 cmd 命令组织成可重复执行的自动化流程。掌握变量、参数、路径、条件、循环、错误判断和延迟变量扩展,就能编写常见的 Windows 简单自动化脚本。
![]()
“点赞有美意,赞赏是鼓励”
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.