bat批处理脚本语法记录
一、基础结构与执行方式
-
创建与命名批处理文件是纯文本文件,扩展名为
.bat(兼容 DOS)或.cmd(Windows 专用,功能更全)。可用记事本创建,例如test.bat。 -
执行方式
- 双击文件直接运行;
- 命令行中输入
文件名.bat执行(需先切换到文件所在目录,或输入完整路径)。
-
基础模板一个简单的批处理示例(注意:这里无论是rem还是::作为注释都只能单独开一行,不然有可能不生效):
@echo off :: 关闭命令回显(不显示执行的命令本身) echo 这是一个批处理示例 :: 输出文本 pause :: 暂停,显示“请按任意键继续. . .”,防止窗口闪退 exit :: 退出批处理
二、核心基础命令
批处理依赖 Windows 命令行工具,以下是常用基础命令:
| 命令 | 功能说明 | 示例 |
|---|---|---|
echo | 输出文本到屏幕;echo off 关闭命令回显 | echo Hello World 输出 “Hello World” |
rem 或 :: | 注释(:: 是更常用的注释方式,不占进程,需单独占一行) | :: 这是一条注释 |
cd | 切换目录(cd /d 路径 跨盘符切换) | cd /d D:\test 切换到 D 盘 test 目录 |
md | 创建目录(支持多级目录) | md new_folder 创建 new_folder 目录 |
rd | 删除目录(/s 删子目录,/q 静默删除) | rd /s /q old_folder 强制删除 old_folder |
del | 删除文件(/f 删只读文件,/q 静默) | del /f /q *.txt 删除所有 txt 文件 |
copy | 复制文件(/y 覆盖不提示) | copy a.txt b.txt /y 复制 a.txt 到 b.txt |
move | 移动 / 重命名文件(跨盘符为复制 + 删除) | move a.txt D:\ 移动 a.txt 到 D 盘 |
ren | 重命名文件 / 目录 | ren old.txt new.txt 重命名文件 |
cls | 清空屏幕 | cls 清除当前窗口内容 |
exit | 退出批处理(/b 仅退出当前批处理,不关闭窗口) | exit /b 退出当前脚本 |
title | 设置窗口标题 | title 我的批处理 窗口标题改为 “我的批处理” |
color | 设置文字 / 背景颜色(前背景色用十六进制,0-9/A-F) | color 0a 黑色背景 + 绿色文字(0 = 黑,a = 绿) |
三、变量:定义与使用
批处理中的变量用于存储临时数据,分为环境变量和自定义变量。
1. 环境变量(系统预定义)
系统自带的变量,可直接通过 %变量名% 访问,例如:
%SystemRoot%:系统目录(通常是C:\Windows)%USERNAME%:当前用户名%cd%:当前目录路径%date%:当前日期(格式:星期 月 / 日 / 年)%time%:当前时间(格式:时:分: 秒。毫秒)
示例:
@echo off
echo 系统目录:%SystemRoot%
echo 当前用户:%USERNAME%
echo 当前时间:%date% %time%
pause
2. 自定义变量(用户定义)
用 set 命令定义,格式:set 变量名=值(等号前后无空格)。访问变量时用 %变量名% 包裹。
示例:
@echo off
set name=张三 :: 定义变量 name,值为“张三”
echo 姓名:%name% :: 输出“姓名:张三”set /p age=请输入年龄: :: 用 /p 接收用户输入,赋值给 age
echo 你的年龄是:%age%
pause
3. 延迟变量扩展(解决代码块中变量更新问题)
在循环或代码块(用 () 包裹) 中,变量默认只解析一次,修改后无法实时生效。需开启延迟扩展解决:
- 用
setlocal enabledelayedexpansion开启延迟扩展; - 用
!变量名!代替%变量名%访问实时值,%变量名%一旦设定就是不会变的,!变量名!会实时获取变量最新值; - 用
endlocal关闭局部环境(可选)。
示例(不开启延迟扩展的问题):
@echo off
set num=0
(set num=1echo 错误结果:%num% :: 输出 0(未实时更新)
)
pause
示例(开启延迟扩展后):
@echo off
setlocal enabledelayedexpansion :: 开启延迟扩展
set num=0
(set num=1echo 正确结果:!num! :: 输出 1(实时更新)
)
endlocal :: 关闭局部环境
pause
四、流程控制:条件判断(if)
if 命令用于根据条件执行不同操作,支持字符串比较、存在性判断、数字比较等。
1. 基本语法
if 条件 命令 :: 条件成立时执行命令
if not 条件 命令 :: 条件不成立时执行命令
2. 常用条件类型
- 字符串比较:
if "字符串1"=="字符串2" 命令(双引号避免空格问题,区分大小写)示例:if "a"=="A" echo 相等(输出空,因为大小写不同) - 文件 / 目录存在性:
if exist 路径 命令示例:if exist test.txt echo 文件存在 - 变量是否定义:
if defined 变量名 命令示例:if defined name echo 变量 name 已定义 - 数字比较:用专用运算符(不支持
><等符号,需用以下缩写):equ(等于)、neq(不等于)、lss(小于)、leq(小于等于)、gtr(大于)、geq(大于等于)示例:if 5 gtr 3 echo 5大于3
3. 代码块与嵌套
复杂逻辑可用 () 包裹代码块,支持嵌套:
@echo off
set score=85
if %score% geq 60 (echo 及格if %score% geq 90 (echo 优秀) else (echo 良好)
) else (echo 不及格
)
pause
五、流程控制:循环(for)
for 命令用于重复执行操作,支持遍历文件、目录、数字、文本内容等,语法灵活。
1. 基本格式
for %%变量 in (集合) do 命令 :: 变量名必须是单个字母(如 %%i、%%a)
%%变量:循环变量(命令行中用%变量,批处理中必须用%%);(集合):要遍历的对象(文件、字符串、数字范围等);do:后续跟循环体命令。
2. 常用循环类型
(1)遍历文件 / 目录(默认)
@echo off
:: 遍历当前目录下的所有 txt 文件
for %%i in (*.txt) do (echo 文件名:%%iecho 完整路径:%%~fi :: %%~fi 是获取文件的完整路径(~f 是扩展参数)
)
pause
(2)遍历目录(/d 参数)
for /d %%i in (模式) do 命令:仅遍历目录,不包含文件。示例:遍历当前目录下所有以 “test” 开头的目录:
for /d %%i in (test*) do echo 目录:%%i
(3)递归遍历(/r 参数)
for /r [目录] %%i in (模式) do 命令:从指定目录开始递归遍历所有子目录。示例:递归遍历 D 盘所有 exe 文件:
for /r D:\ %%i in (*.exe) do echo 找到:%%i
(4)处理文本 / 命令输出(/f 参数)
for /f ["选项"] %%i in (文件/命令) do 命令:按行读取文件内容或命令输出,支持分割、跳过行等。常用选项:
delims=分隔符:按分隔符分割行(默认空格 / 制表符);skip=n:跳过前 n 行;tokens=n:只取分割后的第 n 列(多列用tokens=1,3)。
示例 1:读取文件内容(按行输出 test.txt 的内容):
for /f "delims=" %%i in (test.txt) do echo 行内容:%%i :: delims= 表示不分割,取整行
示例 2:获取命令输出(获取当前目录下的文件数):
for /f %%i in ('dir /b *.txt ^| find /c /v ""') do set count=%%i :: '命令' 中用 ^| 转义管道符
echo txt 文件数量:%count%
(5)数字循环(/l 参数)
for /l %%i in (开始,步长,结束) do 命令:按数字范围循环(步长默认为 1)。示例:从 1 到 5,每次加 1:
for /l %%i in (1,1,5) do echo 数字:%%i :: 输出 1 2 3 4 5
六、特殊符号与运算符
批处理中特殊符号用于控制命令执行逻辑,常用符号如下:
| 符号 | 作用说明 | 示例 | ||||
|---|---|---|---|---|---|---|
& | 同一行执行多个命令(无论前一个是否成功) | echo 第一步 & echo 第二步 | ||||
&& | 前一个命令成功后,再执行后一个(逻辑与) | copy a.txt b.txt && echo 复制成功 | ||||
| ` | ` | 前一个命令失败后,再执行后一个(逻辑或) | `del c.txt | echo 文件不存在 ` | ||
> | 重定向输出(覆盖文件) | echo 内容 > test.txt 覆盖 test.txt 内容 | ||||
>> | 重定向输出(追加到文件) | echo 追加内容 >> test.txt 追加到文件 | ||||
| ` | ` | 管道(前一个命令的输出作为后一个的输入) | `dir /b *.txt | find “test”` 查找含 test 的 txt | ||
^ | 转义字符(处理特殊符号,如 &、 | 、> 等) | echo 输出^&符号 显示 “输出 & 符号” | |||
() | 代码块(将多个命令作为整体执行) | (echo 1 & echo 2) 作为一个块执行 | ||||
% | 变量引用(批处理中用 %%,命令行用 %) | %name% 引用变量 name |
七、函数(用 goto 和 call 模拟)
批处理没有真正的函数,但可通过标签(: 标签名) + goto + call 模拟函数调用。
1. 基本语法
:函数名 :: 定义函数标签函数体命令goto :eof :: 函数结束(返回调用处)call :函数名 [参数1] [参数2]... :: 调用函数,参数用 %1、%2... 接收
2. 示例(定义一个加法函数)
@echo off
call :add 3 5 :: 调用 add 函数,传入参数 3 和 5
pause
exit /b :: 退出主程序:add :: 加法函数,参数 %1 和 %2 为加数
set /a sum=%1 + %2 :: /a 表示算术运算
echo %1 + %2 = %sum%
goto :eof :: 返回
八、错误处理(errorlevel)
每个命令执行后会返回一个错误级别(errorlevel):0 表示成功,非 0 表示失败。可通过 if errorlevel 判断。
1. 基本用法
命令 && 成功处理 || 失败处理 :: 简洁写法
示例(复制文件并判断结果):
@echo off
copy a.txt b.txt /y && (echo 复制成功
) || (echo 复制失败,错误级别:%errorlevel%
)
pause
2. 用 if errorlevel 判断
if errorlevel n 表示 “错误级别>= n”,需从大到小判断:
@echo off
del c.txt
if errorlevel 2 echo 权限不足
if errorlevel 1 echo 文件不存在
if errorlevel 0 echo 删除成功(或文件不存在但无错误)
pause
九、高级技巧
-
调用其他批处理文件用
call 文件名.bat调用,避免直接执行导致当前脚本终止。示例:call sub.bat调用同目录的 sub.bat。 -
获取命令输出到变量结合
for /f和命令,将输出存入变量:for /f %%i in ('echo hello') do set var=%%i :: var 的值为 hello -
批量重命名文件用 for 循环 + ren 命令:
:: 将所有 txt 文件重命名为 前缀_原文件名.txt for %%i in (*.txt) do ren "%%i" "前缀_%%i" -
临时关闭延迟扩展若变量值包含
!,需临时关闭延迟扩展:setlocal enabledelayedexpansion set str=abc!def echo 错误显示:!str! :: 显示 abcdef(! 被解析为延迟变量符号) endlocal :: 关闭延迟扩展 setlocal disabledelayedexpansion echo 正确显示:%str% :: 显示 abc!def
总结
批处理语法核心包括:基础命令、变量(含延迟扩展)、条件判断(if)、循环(for)、特殊符号和函数模拟。通过组合这些功能,可实现文件管理、系统配置、自动化任务等场景。实际使用中需注意路径空格(用引号包裹)、变量解析规则(延迟扩展)等细节。
补充问题:
1.bat的执行流程有哪些
顺序执行(默认行为)
-
逐行解析执行:
cmd.exe从文件第一行开始,依次读取并执行每一行命令(忽略空行和注释)。 -
注释跳过:以
rem或::开头的行被视为注释,直接跳过不执行。 -
命令回显控制:
- 默认情况下,
echo on(开启命令回显),执行的命令会被打印到屏幕(如echo hello会先显示echo hello,再显示hello)。 - 若开头有
@echo off,@表示当前命令不回显,echo off关闭后续所有命令的回显(仅显示命令结果,不显示命令本身)。
示例(顺序执行):
@echo off :: 关闭命令回显 echo 第一步 :: 执行并输出“第一步” md test :: 创建test目录 echo 第二步 :: 执行并输出“第二步”执行流程:从上到下依次执行
echo、md、echo,无跳转。 - 默认情况下,
2.%~dp0作用
%0:批处理中,%0代表当前批处理文件自身的名称(包括调用时使用的路径,可能是相对路径或绝对路径)。例如:如果批处理文件是C:\scripts\test.bat,直接双击运行时,%0就是C:\scripts\test.bat;如果在C:\目录下通过scripts\test.bat调用,%0就是scripts\test.bat。~dp:是对%0的扩展修饰符,用于提取路径信息:d:提取 “驱动器”(如C:);p:提取 “路径”(如\scripts\);- 组合
dp即提取 “驱动器 + 完整路径”。
- 因此,
%~dp0的作用是:将%0扩展为当前批处理文件所在的绝对路径(驱动器 + 目录),且路径末尾一定带\。
3.setlocal enabledelayedexpansion作用
是批处理中用于开启 “延迟变量扩展” 功能的命令,其核心作用是解决批处理中 “代码块内变量实时更新” 的问题,允许在循环、条件判断等代码块中动态获取变量的最新值。
4.goto :eof 的作用:跳转到文件末尾,相当于退出当前过程
5. 2>&1作用
在批处理(.bat)中,2>&1 是一个标准流重定向命令,用于将标准错误流(stderr,编号为 2)的输出重定向到标准输出流(stdout,编号为 1),实现 “错误信息与正常信息合并输出” 的效果。
先理解:标准流的概念
在命令行环境中,程序的输入 / 输出通过 “标准流” 传递,常见的三个标准流及其编号如下:
- 标准输入流(stdin):编号
0,用于接收程序的输入(如用户键盘输入)。 - 标准输出流(stdout):编号
1,用于输出程序的正常执行结果(如echo命令的文本、dir命令的文件列表)。 - 标准错误流(stderr):编号
2,用于输出程序的错误信息(如命令拼写错误、文件不存在的提示)。
默认情况下,stdout 和 stderr 的输出都会显示在屏幕上,但它们是两个独立的流。2>&1 的作用就是将这两个流合并,让错误信息跟随正常信息的 “去向”(如文件、管道等)。
2>&1 的具体含义
2:代表标准错误流(stderr)。&1:&表示 “引用一个流的编号”,1代表标准输出流(stdout)。- 整体
2>&1:将标准错误流的输出重定向到标准输出流当前指向的目标(可能是屏幕、文件、管道等)。
6. sc query "!SERVICE_ID!":查询服务状态
-
sc:Windows 系统的 “服务控制” 命令(Service Control),用于管理系统服务(如启动、停止、查询等)。 -
query:sc的子命令,用于查询服务的状态(如是否存在、运行中 / 停止等)。 -
"!SERVICE_ID!":要查询的服务名称或服务 ID(这里是变量引用)。
SERVICE_ID是一个自定义变量,存储了目标服务的名称(如wuauserv是 Windows 更新服务)。!SERVICE_ID!是延迟变量扩展的引用方式(需先通过setlocal enabledelayedexpansion开启),用于在代码块(如循环、if分支)中实时获取变量的最新值。
7.bat中errorlevel如何获得
在批处理(.bat)中,errorlevel 是一个系统自动维护的 “错误级别” 值,用于表示 “上一条命令 / 程序执行的结果状态”。它的获取和设置完全由系统自动完成,无需手动定义,核心逻辑是:每条命令执行后,系统会根据执行结果自动更新 errorlevel 的值,默认为0,执行失败时非0值,通过%errorlevel%或!errorlevel!可直接获得。
8.bat中type
在批处理(.bat)中,type 是一个用于显示文本文件内容的命令,类似于 Linux 中的 cat 命令。它可以直接输出文本文件(如 .txt、.bat、.ini 等)的内容到屏幕,也可结合重定向或管道符实现更灵活的操作
