四、网络整理BAT脚本——特殊命令(其他)

目录

1. Start

2. Call

a). 基本应用

b). 调用标签(与goto有区别)

c). 调用带参数的批处理

d). start命令与call命令的区别

3. setlocal/endlocal

4. Title

5. color

6. MODE

7. errorlevel

8. Choice

9. assoc 和 ftype

10. pushd 和 popd



1. Start


调用外部程序,所有的DOS命令和命令行程序都可以由start命令来调用。常用参数:

MIN                      开始时窗口最小化

SEPARATE            在分开的空间内开始 16 位 Windows 程序

HIGH                    在 HIGH 优先级类别开始应用程序

REALTIME            在 REALTIME 优先级类别开始应用程序

WAIT                    启动应用程序并等候它结束

parameters         这些为传送到命令/程序的参数

执行的应用程序是 32-位 GUI 应用程序时,CMD.EXE 不等应用程序终止就返回命令提示。如果在命令脚本内执行,该新行为则不会发生。

 

2. Call


在批处理脚本中,call命令用来从一个批处理脚本中调用另一个批处理脚本。

语法:

call [ [Drive:] [Path] FileName [BatchParameters]] [:label [arguments]]

参数:

[Drive:][Path] FileName  指定要调用的批处理程序的位置和名称。Filename 参数必须是.bat 或 .cmd 扩展名的类型文件。

BatchParameters 指定批处理程序所需的命令行信息(即参数项)。

调用另一个批处理程序,并且不终止父批处理程序(如果不用call而直接调用别的批处理文件,那么执行完那个批处理文件后将无法返回当前文件并执行当前文件的后续命令)。

call 命令接受用作跳转目标的标签。如果在脚本或批处理文件外使用call,它将不会在命令行起作用。

a). 基本应用

应用示例:新建两个文本文件,一个命名为call1,修改文件的类型为bat,用编辑内容为:

 

echo running call1

 

另一个命名为call2,修改文件类型为bat,编辑内容为:

 

@echo off

echo start

call call1.bat

echo running call2

echo end

pause>nul

 

双击执行call2文件,执行结果如下所示:

 

start

running call1

running call2

end

 

可以很清晰的看到,call调用类似于函数调用的执行逻辑:call2相当于执行主函数,在其执行过程中,需要调用到call1函数,当call1执行结束后,call2主函数再继续执行本身的命令,直至整个过程结束。

注意:call1脚本第一行没有再写@echo off语句。因为call2第一行已经关闭了命令回显状态,当call2调用call1时,此设置同样有效,由此可更深入理解调用。

 

b). 调用标签(与goto有区别)

新建两个文本文件,一个命名为call3,修改文件的类型为bat,编辑内容为:

@echo off

call :label

echo 1

echo 2

 

:label

echo 3

echo 4

另一个命名为call4,修改文件类型为bat,编辑内容为:

 

@echo off

call call3.bat

pause>nul

 

运行结果为:

 

3

4

1

2

3

4

 

这便表现出call与goto的区别。注意call调用时必须在标签名前加冒号,而goto是直接跟标签名。

同上例,使用goto来执行:

 

@echo off

goto label

echo 1

echo 2

 

:label

echo 3

echo 4

 

结果为:

 

3

4

 

c). 调用带参数的批处理

新建两个文本文件,一个命名为call1,修改文件的类型为bat,编辑内容为:

 

echo %1 %2

echo %3

 

另一个命名为call2,修改文件类型为bat,内容为:

 

@echo off

call call1.bat hello world 123

echo end

pause>nul

 

执行结果为:

 

hello world

123

end

 

d). start命令与call命令的区别

如上文所述,start命令也能调用DOS命令和命令行程序,start与call区别表现为:

start命令应用示例:新建两个文本文件,一个命名为main,修改文件类型为bat,编辑内容为:

 

@echo off

set a=1

pause>nul

echo start startchild.bat

start startchild.bat

echo end start

pause>nul

echo %b%

pause>nul

 

一个命名为startchild,修改文件类型为bat,编辑内容为:

 

@echo off

echo %a%

set b=20

pause>nul

 

双击执行startmain.bat,观察其运行结果如下图所示:

相同的应用,如果改为call命令:新建两个文本文件,一个命名为main,修改文件类型为bat,编辑内容为:

 

@echo off

set a=1

pause>nul

echo call callchild.bat

call callchild.bat

echo end call

pause>nul

echo %b%

pause>nul

 

一个命名为callchild,修改文件类型为bat,编辑内容为:

 

@echo off

echo %a%

set b=20

pause>nul

 

双击执行callmain.bat,观察其运行结果如下图所示:

 

分析结果:

应用示例中,在main.bat中定义了变量a,值为1;在child.bat中定义了变量b,值为20。

main.bat首先执行call child.bat,然后child.bat将执行echo %a%,现在能正常显示1。

call完之后,main.bat将执行echo %b%,也能正常显示20。

那么,如果将call改为start,待child.bat执行完再关闭之后,main.bat继续echo %b%,将无法显示变量b的值,而仅相当于执行echo命令,执行结果为:ECHO处于关闭状态。

call的时候,他们拥有同一个壳cmd.exe,在同一个进程当中,所以他们的变量是互通的。

start的时候,他们拥有两个壳cmd.exe,但child.bat可以看成是main.bat的子进程,子进程可以读取父进程中的变量(即a的值)。

总结结论:

对于start,概况二句话:“不同进程不能传值”,“相同进程单向传值,老子传儿子,非儿子传老子”。

对于call,“同一进程,变量互通”。

另外,可以从以下几方面理解start与call命令的区别:

一是调用范围不同:call主要用来进行批处理的内部调用,如call :pend 和一些dos命令的调用如call set test=2,但也可以调用其他可执行文件,而start则不能进行内部调用,但其可以执行基本上所有的外部程序,还可以执行shell,如打开文件夹start "" "%WINDIR%",安装网络打印机start "" "\\IP\Printer"等等。

二是调用方式不同:call是严格意义上而言的调用,在call另一个批处理时是在同一窗体进程里执行,而start则是执行,所以在执行另外一个批处理时是在不同的窗体进程里进行,也就是说在新开启的进程里执行,虽然start可以加入b参数,但其结果却完全不同。如我们使用call set test=2 和 start /b set test=2 看似执行的结果相同,但是我们发现后者有两个进程,而且在窗体里要执行两次exit才能退出,所以当我们使用start来执行一个批处理后最好在被调用的批处理中也加一个exit,否则无法退出被调用的批处理的dos窗体,但是使用call调用时如果在被调用的批处理中存在exit则会直接结束原始和被调用的批处理程序,这是一个非常严重的问题。建议在被调用的批处理中使用goto :eof来取代exit。

三是调用结果不同:call调用不仅可以把参数或变量传给被调用的批处理,而且被调用的批处理也可以设置参数或变量以便回传,而start只能把参数或变量传给被调用的批处理,却不能回传参数或变量,这一点实际上是第二点的延伸。另外,我们还必须注意一点:使用call调用其他批处理时,在被调用的批处理中若我们使用goto命令的时候,建议要使用与原批处理中不同的标签名来跳转,否则可能会跳转到原批处理中而不能保证完整的执行被调用批处理中的所有语句。

 

3. setlocal/endlocal


启动/结束延迟环境变量扩展功能

前面已经介绍过变量的引用原理,就是查找变量名对应的值来替换“%变量名%”字符串,从而达到变量引用的效果,这个过程也称之为变量扩展过程,这种过程可用于处理基础的普通的变量,然而我们来看看下面的例子:

 

@echo off

set var=before

if "%var%" == "before" (

  set var=after

  if "%var%" == "after" (

    echo 重置var的值成功[var=%var%]

  ) else (

    echo 重置var的值失败[var=%var%]

  )

)

echo var=%var%

pause>nul

 

按照正常的执行流程可以推断出结果为“重置var的值成功[var=after]”,然而真实执行的结果并不是我们想象的,保存为批处理文件并执行输出的结果为“重置var的值失败[var=before]”。我们来看看为什么为出现这种情况?

首先声明了变量var的值为before,紧接着为一个“if”语句,又在“if”语句中对变量var进行重新赋值,然后在进行判断,然而该程序在解释执行的过程中,将“if”语句以及其内的“set”命令和“if”语句作为一整条语句进行解释的

当遇到“%var%”时会自动查找“var”的值替换当前语句,也就是整个外层“if”语句中的所有“%var%”字符串,因此内部的“if”判断条件中的“%var%”被替换成了“before”,所以永远都不会与“after”相等。这就是变量扩展的过程,那么外层“if”语句中的“set var=after”是否执行了呢?答案是肯定的,通过在程序末尾追加“echo var=%var%”可以看出。

通过上面的例子,可以得出一个结论就是批处理中的默认变量替换过程值针对一整条语句的,也就是说如果一整条语句中某个地方有变量的引用,则将会影响到该条语句中的所有变量引用,同一条语句中的所有变量引用会在同一时刻被替换为该变量对应的值。

通俗的说,就是默认情况下,一条语句中的变量的值是固定的

针对这个现象,批处理提出了延迟环境变量(简称延迟变量)的概念,主要用于对变量进行扩展,弥补普通变量的应用过程中的不足,通过延迟环境变量可以实现在一整条语句中改变变量的值。也就是说可以通过延迟环境变量概念来实现子句内部的变量声明、定义和赋值等操作。批处理中给出了“setlocal”和“endlocal”命令来实现延迟变量扩展功能的开启和关闭操作,来看看两个命令的用法:

 

setlocal enableExtensions | disableExtensions

setlocal enableDelayedExpansion | disableDelayedExpansion

endlocal

 

“setlocal”命令有两种用法:

第一种用法用于启动(enableExtensions)或者停用(disableExtensions)命令处理器扩展名功能,这个用法主要用于管理MS-DOS解释器的命令扩展功能,默认是开启的,一般很少用到。

第二种用法就是现在介绍的用于启动(enableDelayedExpansion)或者停用(disableDelayedExpansion)延迟环境变量扩展功能,默认是停用的。“endlocal”命令用法比较简单,就一个单一的命令行,该命令行主要用于停用延迟环境变量扩展功能,命令执行后将会还原当前批处理的扩展功能为默认值,所做的环境变量的改动不在局限于当前批处理文件;实质上“endlocal”比较特殊,是可以省略的,也不是一定要与“setlocal”成对出现,当一个或多个“setlocal”没有强制使用“endlocal”时会在批处理文件的末尾自动执行“endlocal”命令来还原初始默认设置。

当开启延迟环境变量的扩展功能后,对环境变量的修改和引用将会扩展到整个批处理程序中。下面来看看如何使用延迟环境变量的扩展功能?现在使用延迟环境变量扩展功能解决上面遇到的问题,代码如下:

 

@echo off

setlocal enableDelayedExpansion

set var=before

if "!var!" == "before" (

  set var=after

  if "!var!" == "after" (

    echo 重置var的值成功[var=!var!]

  ) else (

    echo 重置var的值失败[var=!var!]

  )

)

pause>nul

 

在这段代码中,首先使用“setlocal enableDelayedExpansion”语句启用了延迟环境变量扩展功能,保存为批处理文件并执行的结果则为预想的效果“重置var的值成功[var=after]”,代码中并没有强制使用“endlocal”语句停用延迟环境变量扩展功能,但是MS-DOS解释器会在程序的末尾,也就是“pause>nul”语句之后自动调用“endlocal”命令重置MS-DOS环境默认值。

但是上面的代码与之前的代码还有一处细小的区别,就是这里使用了“!xxx!”的方式来引用变量。然而为什么要使用这种方式呢?“%xxx%”的方式是否可行?答案可想而知“%xxx%”的方式肯定不可行。之前已经介绍过“%xxx%”方式的变量替换原则,当在一条命令的整体语句中时,如果首次遇到“%xxx%”的字符串,则会自动查找并替换该整条语句中的所有“%xxx%”字符串为指定变量的值;正是这个原因,所以提出了延迟环境变量扩展的概念,延迟环境变量扩展就是为了解决整条语句中所有变量被替换的问题,然而在提出延迟环境变量扩展概念的同时扩展了“!xxx!”的变量引用方式,主要用于区别默认的“%xxx%”变量引用方式,而且“!xxx!”变量引用方式只能在延迟环境变量扩展功能开启的环境中才能被解析。

总结以下,关于延迟环境变量扩展的用法,延迟环境变量扩展功能主要用于解决像“if”、“for”以及各种复合语句(使用逻辑运算符拼接的语句)等中,用于在语句内部引用修改后的变量,因为默认情况下语句中的变量是被提前替换的,使用延迟环境变量则可以延迟替换过程到解析到该变量时;使用“setlocal enableDelayedExpansion”语句开启延迟环境变量扩展功能后,只能使用“!xxx!”的方式引用变量,表示该变量将被作为延迟环境变量进行处理,如果使用“%xxx%”方式引用将继续作为普通变量处理;开启延迟环境变量扩展功能后可以在必要的时候强制使用“endlocal”或“setlocal disableExtensions”语句停用该功能,默认在程序结尾自动调用“endlocal”语句进行重置。

 

4. Title


title BAT的标题

 

5. color


设置字体颜色:COLOR 02 (0代表背景色,2代表前景色)

常用的颜色有以下值:0 黑色,1蓝色,2 绿色,3 浅绿色,4红色,5紫色,6黄色,7白色,8灰色,9浅蓝,A浅绿,B浅蓝色,C浅红色,D浅紫色,E浅黄色,F亮白色)。

如果没有给定任何参数,该命令会将颜色还原到 CMD.EXE 启动时的颜色。这个值来自当前控制台窗口、/T 开关或DefaultColor 注册表值。

如果用相同的前景和背景颜色来执行 COLOR 命令,COLOR 命令会将 ERRORLEVEL 设置为 1。

例如: "COLOR fc" 在亮白色上产生亮红色

6. MODE


配置系统设备。

串行口:     MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s]

                         [to=on|off] [xon=on|off] [odsr=on|off]

                         [octs=on|off] [dtr=on|off|hs]

                         [rts=on|off|hs|tg] [idsr=on|off]

设备状态:             MODE [device] [/STATUS]

打印重定向:           MODE LPTn[:]=COMm[:]

选定代码页:           MODE CON[:] CP SELECT=yyy

代码页状态:           MODE CON[:] CP [/STATUS]

显示模式:             MODE CON[:] [COLS=c] [LINES=n]

击键率:               MODE CON[:] [RATE=r DELAY=d]

 

设置窗体大小:MODE CON: COLS=宽度 LINES=高度

例:

 

mode con cols=113 lines=15 & color 9f

 

此命令设置DOS窗口大小:15行,113列

 

7. errorlevel


程序返回码

 

echo %errorlevel%

 

每个命令运行结束,可以用这个命令行格式查看返回码,用于判断刚才的命令是否执行成功。默认值为0,一般命令执行出错会设 errorlevel 为1。

 

8. Choice


choice 使用此命令可以让用户输入一个字符(用于选择),从而根据用户的选择返回不同的errorlevel,然后于if errorlevel配合,根据用户的选择运行不同的命令。

注意:choice命令为DOS或者Windows系统提供的外部命令,不同版本的choice命令语法会稍有不同,请用choice /?查看用法。

choice的命令语法(该语法为Windows 2003中choice命令的语法,其它版本的choice的命令语法与此大同小异):

 

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 参数时,将参数降序排列。

示例:

 

CHOICE /?

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

CHOICE /T 10 /C ync /CS /D y

CHOICE /C ab /M "选项 1 请选择 a,选项 2 请选择 b"

CHOICE /C ab /N /M "选项 1 请选择 a,选项 2 请选择 b"

 

如果运行命令:

 

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

 

屏幕上会显示:

 

确认请按 Y,否请按 N,或者取消请按 C [Y,N,C]?

 

例:test.bat的内容如下(注意,用if errorlevel判断返回值时,要按返回值从高到低排列):

 

@echo off

choice /C dme /M "defrag,mem,end"

if errorlevel 3 goto end

if errorlevel 2 goto mem

if errotlevel 1 goto defrag

 

:defrag

Echo this is defrag

goto end

 

:mem

Echo this is mem

goto end

 

:end

Echo this is end

 

Pause>nul

 

此批处理运行后,将显示“defrag,mem,end[D,M,E]?” ,用户可选择d m e ,然后if语句根据用户的选择作出判断,d表示执行标号为defrag的程序段,m表示执行标号为mem的程序段,e表示执行标号为end的程序段,每个程序段最后都以goto end将程序跳到end标号处,然后程序将显示good bye,批处理运行结束。

 

9. assoc 和 ftype


文件关联

assoc 设置'文件扩展名'关联,关联到'文件类型'

ftype 设置'文件类型'关联,关联到'执行程序和参数'

当你双击一个.txt文件时,windows并不是根据.txt直接判断用 notepad.exe 打开

而是先判断.txt属于 txtfile '文件类型'

再调用 txtfile 关联的命令行

 

txtfile=%SystemRoot%\system32\NOTEPAD.EXE %1

 

可以在"文件夹选项"→"文件类型"里修改这2种关联

Assoc                         #显示所有'文件扩展名'关联

assoc .txt                  #显示.txt代表的'文件类型',结果显示 .txt=txtfile

assoc .doc                 #显示.doc代表的'文件类型',结果显示 .doc=Word.Document.8

assoc .exe                 #显示.exe代表的'文件类型',结果显示 .exe=exefile

ftype                          #显示所有'文件类型'关联

ftype exefile             #显示exefile类型关联的命令行,结果显示 exefile="%1" %*

 

assoc .txt=Word.Document.8

 

设置.txt为word类型的文档,可以看到.txt文件的图标都变了

 

assoc .txt=txtfile

 

恢复.txt的正确关联

 

ftype exefile="%1" %*

 

恢复 exefile 的正确关联

如果该关联已经被破坏,可以运行 command.com ,再输入这条命令

 

10. pushd 和 popd


切换当前目录

 

@echo off

c: & cd\ & md mp3       # C:\ 建立 mp3 文件夹

md d:\mp4               # D:\ 建立 mp4 文件夹

cd /d d:\mp4            #更改当前目录为 d:\mp4

pushd c:\mp3            #保存当前目录,并切换当前目录为 c:\mp3

popd                    #恢复当前目录为刚才保存的 d:\mp4

 

一般用处不大,在当前目录名不确定时,会有点帮助。(dos编程中很有用)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值