本文用于记录基础的bat批处理文件编写方法,只进行简单的学习,不会过多深入。
文章名:bat批处理命令
作者:遮瑕修改时间:2022年11月26日
本文主要内容来自批处理之家
一、什么是bat批处理
批处理文件(Batch File,简称 BAT文件)是一种在DOS 下最常用的可执行文件,所谓的批处理,就是按规定的顺序自动执行若干个指定的DOS命令或程序。也就是说,其实质上就是把一系列基础的DOS命令按顺序书写,而后保存为.bat
文件。
注:由于.bat文件是基于16平台下的程序,在Windows NT及以后的32位中运行时偶尔会出现堆栈溢出之类的错误,所以建议在新的系统中尽可能的采用.cmd
扩展的批处理文件代替.bat的文件。
二、批处理基本语法
首先我们得知道最简单的批处理怎么写,我们下面尝试在控制台输出一个Just Do It
。
@echo Just Do It @pause
显示为:
运行示范
我们来逐字分析:
- 首先是
@
的作用,使用它可以告诉电脑不要显示你现在这一句话,如果不加的话,显示会变为:
C:\Users\86187\Desktop>echo Just Do It Just Do It C:\Users\86187\Desktop>pause 请按任意键继续. . .
这里我将bat文件放到了桌面,桌面绝对路径为C:\Users\86187\Desktop
。
- 其次是
echo
和pause
,它们都是批处理的命令,也就是说是可以直接输入到控制台执行的。
echo:告诉电脑显示其后的内容。
pause:告诉电脑执行到这里的时候暂停,如果不使用的话bat会直接执行完,也就是只会瞬间闪过一个黑框。
以上就是bat批处理的基础编辑,可以看到,虽然类似于编程语言,但是其终究是由指令组成,所以没有很多的语法限制,主要明白命令的用法就好。
三、常用批处理命令
以下按各命令的功能进行分类,但是部分分类包含了个人主观判断,可能不太准确。由于命令过多,因此只会列出部分命令,需要使用时可自行搜索查询。
(一)控制台显示相关
1.注释
- rem
rem是一条命令,在运行的时候相当于把rem本身及其后面的内容置空,起到注释的作用。同时既然它是一条命令,就必须处于单独的一行或者有类似“&”的连接符号连接。- ::
批处理遇到:
会将其后面的语句识别为标记,之所以::
可以起到注释的作用,是因为:
不是标签的合法字符,而系统在这里只知道它是标签而不处理,其他的均交给goto处理,所以使用其他的标签当作注释也是可以的,但是需要确保这个标签不会被goto使用。2.回显设置echo与@
- ehco
echo Hello World
显示当前命令的位置,同时输出Hello World。
- @+命令
@echo Hello World
只输出Hello World,但是不显示当前命令的位置。
- echo off
echo off
从下一行开始关闭回显(当前这一句会显示出来)
- echo on
echo on
从下一行开始开启回显(当前这一句不显示)
- echo
echo
显示当前回显是on还是off
- echo.
echo.
输出回车换行,也就是显示一个空白行
3.cmd窗口显示
- cls
cls
清空当前窗口显示
- title
title 123456
将CMD窗口的标题修改为123456
- color
color 12
将背景修改为蓝色(1),将文字修改为绿色(2)。
颜色对应为黑(0)、蓝(1)、绿(2)、湖蓝(3)、红(4)、紫(5)、黄(6)、白(7)、灰(8)、淡蓝(9)、淡绿(A)、淡浅绿(B)、淡红(C)、淡紫(D)、淡黄(E)、亮白(F)。(二)命令运行逻辑处理相关
1.暂停批处理执行
- pause
pause
暂停批处理的执行,直发生任意键输入为止。
2.条件语句相关
- if
if "%str%"=="test" (echo OK) else echo NO
如果str等于text就输出OK,反之输出NO,也就是:
if 判断语句 (为真的执行语句) else (其它情况的执行语句)
同时结合部分命令可以构成特殊用法,例如可以判断变量是否被定义:if defined str3 (echo str3已经被定义) else echo str3 没有被定义
注:
对于数值判断,批处理不能使用>、<等符号,而是使用:
EQU - 等于
NEQ - 不等于
LSS - 小于
LEQ - 小于或等于
GTR - 大于
GEQ - 大于或等于
- errorlevel
其不为命令,而是一个变量,代表了语句是否正常执行,初始值为0,一般上一条命令的执行结果返回的值只有两个,成功用 0 表示,失败用 1 表示。对于部分特殊命令,会有从0到255之间的值进行执行状态表示。
例如xcopy默认的errorlevel值就有5个,0为复制文件成功,1为未找到复制文件,2为用户通过CTRL C 终止了xcopy操作,4为出现了初始化错误,5为出现了磁盘写入错误。
3.循环语句
- 基础for循环
FOR %%variable IN (set) DO command [command-parameters]
%%variable:指定一个单一字母可替换的参数。如果是CMD窗口,请使用 %variable。
(set):指定一个或者一组文件,可以使用通配符。
command:指定对每个文件执行的命令。
[command-parameters]:指定对每个文件执行的命令。
需要注意的是:在cmd窗口
中,for之后的形式变量I必须使用单百分号引用,即%I;而在批处理文件
中,引用形式变量I必须使用双百分号,即%%I。例如循环输出%i:
FOR %i IN (1 2 3 4 5) DO (echo %i)
输出结果为:
C:\Users\86187>(echo 1 )
1
……
C:\Users\86187>(echo 5 )
5
--特殊用法--:我们可以使用for循环输出当前目录下的某一个指定类型的文件,例如:for %%i in (*.mp3) do echo %%i
简单来说,其会先执行括号内的内容,也就是先执行
.mp3
,获取当前目录下所有拓展名为.mp3的文件,并把它们作为一个合集,每个文件名就是一个元素,类似{a.mp3 b.mp3 c.mp3},然后依次替代%%i执行do后的命令。
综上,可以利用其循环执行的特性进行轮询,从而实现更多功能。例如可以轮询查询A、B、C……盘是否存在,从而判断出哪些盘存在。
- 带参for循环
- for /f
- for /r
- for /d
- for /i
4.跳转命令
- goto
goto label
跳转到指定的标签行(label),标签定义使用
:label
。5.变量
- 定义变量
set aaa = hello
- 变量为数值
set /A aaa = 123
- 变量调用
echo %aaa%
显示变量aaa的内容。
(三)目录及文件操作相关
1.显示dir
- dir:显示当前目录所有内容,不包括隐藏文件
- dir /a:显示当前目录中的文件和子目录,包括隐藏文件和系统文件
- dir *.exe:显示当前目录室友.exe文件
- dir . :显示当前目录中的文件和子目录
2.当前所处目录cd
- cd aaa:跳转到当前目录下的aaa文件夹内
- cd ..:返回上一级目录
- cd\:返回根目录
- cd:显示当前目录
- cd /d D:\Data:跳转到D:\Data目录
3.创建目录md
- md abc:在当前目录创建abc文件夹
- md D:\a\b\c:如果不存在,则自动创建
4.删除目录rd
5.删除文件del
6.文件重命名ren
(四)系统操作相关
1.操作注册表reg
2.注册dll文件regsver32
3.打开文件、运行程序start
4.显示进程tasklist
5.关闭进程taskkill
6.查看IP配置ipconfig
7.解析地址arp
8.传输文件ftp
9.配置网络信息netsh
10.调用外部程序call
(五)小知识点
本节讲解部分需要讲解,但是又不是命令的内容。
1.*
星号在其中表示任意,比如*.txt就是所有格式为.txt的文件。
2.?
?用于代替一位,例如??.txt就是名字为两位的.txt文件。
3.变量延迟
在介绍变量延迟之前,我们先了解批处理的执行逻辑引起的现象:
@echo off set num=0&&echo %num% pause
当以上语句执行时,显示结果为:
ECHO 处于关闭状态
仅从语句上分析,这里应该是先给num赋值0,而后通过echo进行显示,但是实际上执行却没有成功输出0。
要分析其原因,我们首先要知道批处理的执行过程,也就是“自上而下,逐条执行”,从上而下
没有问题,在这里有问题的是逐条执行
,这里的条
是完整的一条语句的意思,在批处理中一条语句并不一定只有一行,例如一个for循环有可能书写很多行,但是这些行加一起才是一条for循环指令。
而后我们需要知道预处理
,也就是在一条代码执行之前会直接对这一条代码进行一些初步处理,其中就包括识别出关键字、将变量的值进行替换,直接将变量替换为其0值,例如aaa为5,那就直接将语句中的aaa替换为5。也就是说,如果命令语句中含有变量引用(变量及紧邻它左右的百分号对),并且某个变量的值在命令的执行过程中被改变了,即使该条语句内部的其他地方也用到了这个变量,也不会用最新的值去替换它们,因为某条语句在被预处理的时候,所有的变量引用都已经被替换成字符串常量了,变量值在复合语句内部被改变,不会影响到语句内部的其他任何地方。
综上,我们已经可以判断出来原因了,也就是num在最初并没有值,所以echo后面被赋值为空,也就是说,语句变为:
set num=0&&echo
所以才会输出echo状态。
为了验证以上说法,我们可以进行以下测试:@echo off set num=5 set num=0&&echo %num% pause
以上批处理输出结果为:5
。验证成功。
为了解决以上问题,我们可以采用变量延迟扩展语句,让变量的扩展行为延迟一下(官方称为扩展,实际上就是对变量用其值进行替换)。变量扩展有两种手段:
- setlocal enabledelayedexpansion 语句
(set是设置的意思,local是本地的意思,enable是能够的意思,delayed是延迟的意思,expansion是扩展的意思,合起来,就是:让变量成为局部变量,并延迟它的扩展行为。)
通过使用该语句,可以直接进行延迟,需要注意的是变量的%
需要修改为!
,例如:@echo off setlocal enabledelayedexpansion set num=0&&echo !num! pause
- call 语句
相对于使用call调用了其自己,从而实现了变量延迟,即:@echo off set num=0&&call echo %%num%% pause
以上为所有的基础笔记,如果想深入学习,可以去批处理之家阅读前辈们分享的文章。