批处理详解
一:批处理是什么
批处理是什么?我们学习批处理,先弄懂这个问题,个人认为第一批处理是一个文本文件,可以使用任何一种文本编辑器编写,正是基于这个特点有时候我们不想让别人看到我们书写的代码而使用bat2com和bat2exe将其转换成exe文件,第二批处理是一种解释性程序,它的功能类似于意念,说强很强说弱又很弱,说它是一种程序更重要的是它和其他编程语言一样有自己的控制结构!而且这个程序有个特点就是解释执行即逐行逐句的翻译执行,这个特点我们在后面还会提到!第三任何批处理都是一个DOS的外部命令,这使得我们在编写批处理的时候可以使用参数,这里的参数不是指DOS命令的命令参数,后面的内容会做解释!
学习批处理第一个需要解决的问题就是特殊符号!
二:批处理中的特殊符号
学会批处理中的特殊符号对于我们学习编写批处理是非常有用的!这里我做了一下简单的整理——:、::、&、&&、>、>>、|、||、nul、con、%、(),成对出现的东西是非常容易记忆的,下面我们结合具体的操作仔细的理解!
1:“:”与“::”
“::”与rem命令是一样效果,起解释说明的作用,和C++中的/……/一样!
“:”符号的作用是标记一个标签与goto语句一起使用,其格式为: label,这点与C或C++中的goto语句是截然相反的,在C或者C++中的格式为label:!举例说明:
@echo off
::标签的使用与goto语句
goto test
:test
echo goto语句test
当然goto语句的跳转是有条件,在后面的批处理结构中你会发现goto语句的魅力,这里只是为了更好的理解上面的两个特殊符号!
2:“&”与“&&”
“&”与“&&”符号的作用是连接两个命令同时执行,区别在于前者不管第一条命令的执行是否成功,都会执行第二条命令,而后者只有在第一条命令执行成功以后才执行后面的命令!例子我们在学完第三组命令“|”与“||”在举!
3:“|”与“||”
“|”符号的作用是将|前执行的命令结果作为其后DOS命令的参数,比如dir|find "2008",dir 命令查看当前目录的文件,然后所有目录的列表作为find "2008"的参数,也就是从该文件目录下查所有2008年建立的文件!
“||”符号的作用与“|”是截然不同的,它也是连接两个命令同时执行,不过是第一条命令执行错误的条件下才会执行第二条命令!
编写如下代码,保存为checkuser.bat:
@echo off
set a=
set/p a=请输入要查的用户名
net user %a% >nul 2>nul && echo 存在该用户|| echo 用户不存在.
这是Visual bat程序安装目录中非常经典的一个批处理,它的作用是检查用户输入的帐户是否存在,当用户输入账户后,比如hacker,然后执行net user hacker,如果是存在该帐户
也就是说命令执行成功了,那么就显示存在该用户,如果不存在该帐户也就是net user hacker命令没执行成功,就显示用户不存在,结合上面的内容我想您已经理解“||”“&&”“&”三者的微妙之处了!
4:“nul”和“con”
在checkuser.bat中,我们看到>nul 2>nul的句子,前者是当命令执行成功后不显示回显,比如net user hacker /ad >nul这样用户添加成功后也不会有提示,后者是命令执行错误后不显示回显,两者同时使用的结果就是不论命令执行是否成功,都不显示任何信息!对于“nul”这个特殊符号我们可以理解为空字符的意思,除了不显示回显,还可以使用它删除文件,copy nul &或者type nul&,这种删除方式是比较安全的,我想当初李开复如果使用这种方法删除文件,也许就不会招来因为跳槽而导致的官司!
对于“con”,我们可以简单的理解为屏幕,在cmd下我们输入:copy *.txt con,可以连续打开多个txt文件以方便我们查看!
5:“>”与“>>”
“>”它的作用是创建一个文件比如echo hacking &,而“>>”的作用是将内容追加到一个文件后面,比如前面1.txt的内容为hacking,在CMD下输入echo hacker>&,那么1.txt 的内容为hackinghacker!
6:“%”与“()”
把这两个符号放一起有点牵强,“()”起分隔符的作用,在后面的批处理中你会理解这点,在批处理我们可以理解为存在两个分隔符一是空格另一个是括号,这时候的“()”类似于c或者c++中的语句结束符“;”,很多时候我们还使用它包括多条DOS命令,这时候又有点类似于c 或者c++中的{},起包含语句块的作用!
“%”它的作用是表示变量,而且在批处理文件和在命令行下书写格式不一样,在命令行下使用%variables,在批处理中我们使用%%variables或者%variables%(不同命令使用不同格式),对于原因,我想它类似于c或者c++中的“转义”,在编程语言中,为了某些特殊的需要提出了“转义”的概念,顾名思义就是转变符号的原有意思,比如\a是响铃!举个例子来说明%的意思,在C++中我们要在屏幕上输出一个“\”,则应该写做cout<<"\\";,如果要输出两个“\”则应该写成cout<<"\\\";,这个过程有个很好听的名字“脱逸”,%也遵循了这样方法,在后面我们将结合for命令详细的说明!
提到“%”号,就不得不说一下参数,所谓参数是在批处理文件(开始说的每个批处理文件是一个外部命令)后所添加的以空格分隔的字符串,它的使用方法是%1-9,参数是针对批处理文件做为一个外部命令来说的,虽然参数和变量不是一个概念,但是它是按变量来处理的,所以有时候我们也就称为变量了!举例说明!
@echo off
md %1
md %1\天下1
md %1\天下2
md %1\天下3
保存为test.bat我们在CMD下输入:test.bat 天下,执行后会在批处理目录中建立一个名字为“天下”的文件夹而且在该文件夹下会一次建立三个子文件夹,这当我们输入“test.bat 天下”的时候“天下”就作为参数传递给了%1,即%1=天下!
另外%variables%的作用是引用环境变量!环境变量可以简单理解为系统已经设置好的系统变量比如%systemroot$是c:\windows,%compsec%代表的是
c:\windows\,对于系统设置好的环境变量我们可以在CMD下输入set
查询,当然我们也可以使用set命令设置环境变量!
下面我们看批处理中的控制结构!
批处理文件怎么做
三:批处理中控制结构
批处理中有四种控制结构:if结构、goto结构、for循环结构、call结构!,对于call和goto 结构应该算是以类,主要是因为它们都具有跳转功能,让很多小批处理转化成大批处理,有点结构化程序设计的味道!
call命令的作用是调用其他的批处理文件,比如:call test.bat,而goto语句在文章开始我们就做了解释,所以我们主要说的就是if结构与for循环结构,首先我们先理解条件这个词的意思,把世界看成一个连锁体系,每一个事情的前一个事情就是该事情的条件,举个简单的例子,我们坐公交车前需要有1元的零钱,这里1元的零钱就是我们坐车的一个条件,当然在批处理或者程序中就不能那么的表达,在C++中条件其实只有两种:一种靠关系运算符实现,一种靠逻辑运算符实现,批处理中也遵循了这样的规则,当然在批处理使用最多条件还是靠“=”来实现!
(一)if结构
在CMD下输入if /?,我们会发现if有三种结构,我们先看这三种结构!
1:IF [NOT] exist filename command
这应该是最简单的一种IF结构,例如if exsit c:\1.txt  、if not exsit c:\1.txt  echo xxx>c:\1.txt!
2:IF [NOT] ERRORLEVEL number command
对于number,在DOS时代这个东西有N多比如1、2、3等等而且每个数字都有不同的意义,并且多个number排列时还有规则,在Windows中其实我们只要注意0和1就可以了!0代表的是程序执行成功,1代表的是程序执行失败!我们可以简单将errorlevel理解为一个变量!所以这个命令还可以这样书写:IF [NOT] %ERRORLEVEL%==number command
我们举个简单的例子:
net user hacker 123 /ad
if %errorlevel%==0 echo 添加帐户成功
上面的内容我们还可以这样写:
net user hacker 123 /ad
if not %errorlevel%==1 echo 添加帐户成功
这两种表达看似等效,其实并不等效,第一个是只有用户添加成功的时候才显示添加帐户,而第二种的意思是不管添加成功还是本机已经存在该帐户,都会显示添加帐户成功,它们之间存在细微的差别!not相当于一个修饰,大家要善于分析条件!
3:IF [NOT] string1==string2 command
这种if结构也是非常有用的,这里首先需要注意等号是两个,其次注意引号并不是必须的,我们可以不加引号,加引号只是为了防止空字符!
举例说明,以前很多文章中都涉及到cmd加密器的问题,就是让用户在运行cmd的时候,首先输入密码!网上有更复杂的,其实批处理学到这里我们就可以写出一个比较简单的cmd 加密程序!
@echo off
set /p %%a=请输入密码
if %%a==hacker goto test
:test
echo 密码正确,登陆成功
start %comspec%
3:if……else结构
在运行上面的批处理过程中,你会发现我们输入任何字符都可以运行cmd!编辑如下代码就不会出现上面的问题了!
@echo off
set /p %%a=请输入密码
if %%a==hacker (goto test) else goto error
:test
echo 密码正确,登陆成功
start %comspec%
:error
echo 密码错误
这里我们不讨论为什么会出现这样的错误,我们看在批处理中if……else结构的具体使用!在文章开始我们提到批处理是逐行逐句解释执行的,所以我们在用到if……else语句时,最好直接写到一行,写到一行我们需要注意,将if后面的命令,简称if子句,用括号括起来就好了,我想原因也许还是逐行逐句解释执行的,这里的()起的作用和空格一样就是分隔作用(上面提到过),一句话if……else语句,在批处理需要放到一行,并且if子句需要用括号括起来!
5:/i开关
if结构语句中有一个开关/i,使用该开关,在执行字符串比较的时候不会区分大小写!而且还可以使用如下运算符:
EQU - 等于
NEQ - 不等于
LSS - 小于
LEQ - 小于或等于
GTR - 大于
GEQ - 大于或等于
书写如下代码:
if /I %time% LEQ 06:00:00.00 goto g1
if /I %time% LEQ 12:00:00.00 goto g2
if /I %time% LEQ 18:00:00.00 goto g3
if /I %time% LEQ 24:00:00.00 goto g4
:g1
net user administrator 123 && goto end
g2:
net user administrator 456 && goto end
g3:
net user administrator 789 && goto end
g4:
net user administrator 023 && goto end
:end
echo OK %time% 密码修改成功,下次登陆请注意
这段代码的意思是根据当前系统时间自动修改计算机登陆密码!结合上面的解释,应该很容易明白,所以这里不在做说明!
下面说批处理的精华所在for循环结构!
(二):for循环结构
1:for variable in (Set) do command (command-paremts)
循环的意思是一次次的重复操作,至于操作什么,如何操作,操作多少次,我们都需要运用命令去自己设定!
CMD下的for循环基本结构:for variable in (Set) do command (command-paremts)
对于上面的结构首先我们先明确批处理中的for循环结构有三个关键字——for、in、do,这是使用for循环结构必不可少的!对于变量我们需要注意在批处理文件中遵循%%即双百分号,在cmd中一般使用%即单百分号,而且在for循环中变量只有52个,(a-z A-Z)可用,对于set的理解就多了,是一个很模糊的概念,可以是一个循环条件,也可以是一个文件、一个目录,command不仅可以是一堆DOS命令,还可以是一个批处理文件,所以后面才可以添加command-paremts!
比如for %i in (*.bat *.txt) do del %%i, 这条语句是指,在当前目录下搜索所有BAT和TXT 文件,并逐个将搜索到的文件名存入变量%%i中,每搜索到一个,就执行del命令删除%%i 变量中指定的文件。
for循环的/D参数和该用法是一样的,就不在单独说明/D参数的使用方法了!
2:FOR /L %variable IN (start,step,end) DO command [command-parameters]
参数/L用来将循环指定在一个数字集合内,指定了起始数,每次循环递增/减的数字,以及当数字超出什么范围时循环结束。例如:for /L %c in (3,1,5) do echo %c!
这条语句是指循环开始时首先将3这个数字存入变量%%c中,并用echo语句显示出来,然后循环每执行一次,这个存入的数字就加1(即在命令格式中的“步进”值),直到数字超出5,循环结束。这段语句的结果是依次显示3、4、5。
3:FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
这个格式操作的对象是一个文件集合,可以是一个目录的名称,也可以是使用通配符的文件名,另外,还可以使用形如“1. 3.txt”的文件集。/R的参数是让for支持子目录搜索!比如在在肉鸡上我们见到了很多txt文件,我们单个下载太复杂了,可以在CMD下输入:for %i in (*.txt) do copy /+%,将所有txt文件合并为一个文件!
4:FOR /F ["options"] %variable IN (set) DO command [command-parameters]
姓名年龄地址性别  QQ  稿件日期
test1  120  中国男  123456    2008-1-1
test2  130  韩国女  9876543  2008-2-2
…………………………
…………………………
现在我们只想要姓名和QQ两列内容,我们可以在CMD下运行:for /f "eol=; tokens=1,5 delims=, " %i %j in () do echo %i %j >> ,如图1所示的运行结果!在我们运行的命令中,“eol=;”是指忽略以分号开头的行,就是说如果某一行如果类似于
“;test1……”,那这行将不被循环处理。“tokens=1,5”是指提取分离出来的第1个和第5个元素,“delims=,”是指分割方式,空格和“/”则无需指定,直接作为默认分割符。经过这样分离循环后,一行中的第1个和第5个元素被分别赋值给了变量%%i和%%j,刚才一行资料中的第1个元素是姓名,而第5个元素则是QQ,然后再将这两个存有所需元素的变量值追加写入到中,之所以用追加写入,是因为循环要处理很多行,如果不使用“>>”追加在末尾的话,则会覆盖掉上一行循环中写入的数据。这点往往是我们for循环语句执行得不到正确文件的原因,在使用for循环结构生成文件的时候需要特别注意!
另外还有一个参数经常用到——skip,它指定了循环从什么时候开始执行,比如for /f %i in (1.txt) do ,我们运行后,批处理会不处理1.txt文件中的第一行内容!
5:“%”与“%%”
前面我提到变量的使用原则,很多人都不明白这个原因,通过for循环结构可以很好的理解,为什么这么说呢?首先,命令行中使用for时不需要双%,这源于命令解释器对命令行与批处理的处理方式不同!其次在批处理文件中使用双%,因为for功能实现需要执行多条语句,因此它必须也具有对命令行(do关键字后的命令)分析处理的功能,而CMD实现for时自然会借用自身原有的命令行分析模块,因此for具有二级转义的特性(转义在前面特殊符号%的时候已经说明),for中do后的语句被分两级解释,第一级在CMD读入并解释for命令行时,第二级在for读入并解释do命令时,它通常会对同一命令行的进行多次解释。在CMD中使用的变量在经过第一级转义后,被替换成特定的不变的字符串常量,参与for 循环的所有执行过程,而替代变量时则要求在执行(do关键字后的命令)过程中不断的动态变化,正式这个变化,我们的变量必须保持其原有变量的特性,而不是转换成一个字符常量!
也就是说,在批处理文件中为了维护do关键字后面的命令动态的执行,确切的说是为了让每次do后命令执行完毕后参数依然是个变量,我们必须使用双%,结合在前文中举的C++例子我想大家应该可以理解了!
四:set命令详解
批处理我们开始的时候就给出了一个定义——它是一种程序,既然是一种程序,它就应该有变量,所谓的变量是以人为参考的,对于人来说变化的量我们都称之为变量!在批处理中我们使用set命令进行自定义变量的设置!
1:SET [variable=[string]]
这是最简单的一种set命令格式,首先注意在set命令中等号只有一个,这和if结构中的个数是不一样的,其次注意在set命令中变量使用%variable%的格式,这和for语句中的变量使用格式是不一样的!一句话,set命令和if、for命令都又差别!
我们输入如下代码,保存为test.bat!
@echo off
set var=这里设置变量值
echo %var%
set是命令var是变量名=(只有一个)号右边的"我是值"是变量的值
在批处理中我们要引用这个变就把var变量名用两个%(百分号)扩起来,如例子中的%var%!2:  SET /P variable=[promptString]
这个格式是常用的,它就像c++中的iostream头文件,让批处理实现了交互执行!将test.bat 的内容修改为如下代码:
@echo off

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。