【批处理DOS

您所在的位置:网站首页 如何取消word中宏的禁用命令窗口 【批处理DOS

【批处理DOS

2024-07-10 11:04:53| 来源: 网络整理| 查看: 265

一、对exit命令和goto命令的基本认知

打印exit命令的帮助信息,执行命令【exit /?】。

C:\Users\Administrator>exit /? 退出 CMD.EXE 程序(命令解释器)或当前批处理脚本。 EXIT [/B] [exitCode] /B 指定要退出当前批处理脚本而不是 CMD.EXE。如果从一个 批处理脚本外执行,则会退出 CMD.EXE exitCode 指定一个数字号码。如果指定了 /B,将 ERRORLEVEL 设成那个数字。如果退出 CMD.EXE,则用那个数字设置 过程退出代码。

打印goto命令的帮助信息,执行命令【goto /?】。

C:\Users\Administrator>goto /? 将 cmd.exe 定向到批处理程序中带标签的行。 GOTO label label 指定批处理程序中用作标签的文字字符串。 标签必须单独一行,并且以冒号打头。 如果命令扩展被启用,GOTO 会如下改变: GOTO 命令现在接受目标标签 :EOF,这个标签将控制转移到当前 批脚本文件的结尾。不定义就退出批脚本文件,这是一个容易的 办法。有关能使该功能有用的 CALL 命令的扩展描述,请键入 CALL /?。

二、“3种命令”和各种执行情况

从上面的帮助信息,我们也可以了解到,如果不考虑exit指令的exitcode,那么一共有3种退出cmd窗口或者批处理脚本程序(子程序)的方法,分别是【exit】、【exit /b】、【goto :eof】。

但是,上面3种方法对应的3条指令,在各个位置(情况)执行的结果却大有不同。

下面这张思维导图,尽可能列举了各种有几率存在差异的情况。

看上去一共有14种情况,但其实有一些情况在测试过程中表现出明显的同一性,可以划等号(绿色箭头连接),而叠加环境的情况在bat文件中完全不应该存在。详见后续的2.1-2.3。

在此直接给出简化的测试思维导图,直接用【双击执行bat】代替用【cmd窗口执行bat】,直接用【call调用脚本内部子程序】代替【call外部调用】,直接用【不叠加环境】执行脚本。

2.1 双击执行bat和在cmd窗口执行bat相同

下面的3大测试,最后的结果都是一模一样的,也印证了本节标题所述之言!

(1)对exit的测试

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call D:\D-desktop\demo.bat pause

再在同一目录新建一个demo.bat文件,代码如下

@echo off echo "子程序开始执行" echo "下一条执行exit" exit echo "子程序的exit执行完了"

直接双击执行main.bat,cmd窗口打开的瞬间又闪退。

而在手动打开的cmd窗口中执行main,这个手动打开的cmd窗口也闪退。

 (2)对exit /b的测试

 在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call D:\D-desktop\demo.bat pause

再在同一目录新建一个demo.bat文件,代码如下。

@echo off echo "子程序开始执行" echo "下一条执行exit /b" exit /b echo "子程序的exit /b执行完了"

直接双击执行main.bat,cmd窗口打开后,能正常输出,值得注意的是【echo "子程序的exit /b执行完了"】并没有输出,因为执行【exit /b】后就退出demo.bat程序了。

而在手动打开的cmd窗口中执行main,这个手动打开的cmd窗口也输出了和上面【双击执行】一样的结果。

(3)对goto :eof的测试

 在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call D:\D-desktop\demo.bat pause

再在同一目录新建一个demo.bat文件,代码如下。

@echo off echo "子程序开始执行" echo "下一条执行goto :eof" goto :eof echo "子程序的goto :eof执行完了"

直接双击执行main.bat,cmd窗口打开后,能正常输出,值得注意的是【echo "子程序的goto :eof执行完了"】并没有输出,因为执行【goto :eof】后就退出demo.bat程序了。

而在手动打开的cmd窗口中执行main,这个手动打开的cmd窗口也输出了和上面【双击执行】一样的结果。

 

2.2 call调用脚本内子程序和call调用外部脚本相同

下面的3大测试,最后的结果都是一模一样的,也印证了本节标题所述之言!

2.2.1 对exit的测试

 (1)先测试【call调用脚本内子程序】的情况~

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call:demo pause :demo echo "子程序开始执行" echo "下一条执行exit" exit echo "子程序的exit执行完了"

直接双击执行main.bat,cmd窗口打开后,瞬间关闭(闪退),说明执行exit会直接闪退。

(2)接着测试【call调用外部脚本】的情况~

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call D:\D-desktop\demo.bat pause

再在同一目录新建一个demo.bat文件,代码如下。

@echo off echo "子程序开始执行" echo "下一条执行exit" exit echo "子程序的exit执行完了"

直接双击执行main.bat,cmd窗口打开后,瞬间关闭(闪退),说明执行exit会直接闪退。

2.2.2 对exit /b的测试

 (1)先测试【call调用脚本内子程序】的情况~

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call:demo pause :demo echo "子程序开始执行" echo "下一条执行exit /b" exit /b echo "子程序的exit /b执行完了"

直接双击执行main.bat,cmd窗口打开后,能正常输出,值得注意的是【echo "子程序的exit /b执行完了"】并没有输出,因为执行【exit /b】后就退出demo.bat程序了。

另外:命令【exit /b】不要写成了【exit \b】,如果写错了cmd会将其识别成【exit】,cmd窗口就会闪退!

(2)接着测试【call调用外部脚本】的情况~

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call D:\D-desktop\demo.bat pause

再在同一目录新建一个demo.bat文件,代码如下。

@echo off echo "子程序开始执行" echo "下一条执行exit /b" exit /b echo "子程序的exit /b执行完了"

直接双击执行main.bat,cmd窗口打开后,能正常输出,值得注意的是【echo "子程序的exit /b执行完了"】并没有输出,因为执行【exit /b】后就退出demo.bat程序了。

2.2.3 对【goto :eof】的测试

(1)先测试【call调用脚本内子程序】的情况~

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call:demo pause :demo echo "子程序开始执行" echo "下一条执行goto :eof" goto :eof echo "子程序的goto :eof执行完了"

直接双击执行main.bat,cmd窗口打开后,能正常输出,值得注意的是【echo "子程序的goto :eof执行完了"】并没有输出,因为执行【goto :eof】后就退出demo.bat程序了。

(2)接着测试【call调用外部脚本】的情况~

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" call D:\D-desktop\demo.bat pause

再在同一目录新建一个demo.bat文件,代码如下。

@echo off echo "子程序开始执行" echo "下一条执行goto :eof" goto :eof echo "子程序的goto :eof执行完了"

直接双击执行main.bat,cmd窗口打开后,能正常输出,值得注意的是【echo "子程序的goto :eof执行完了"】并没有输出,因为执行【goto :eof】后就退出demo.bat程序了。

2.3 在脚本中叠加环境对“3种命令”的影响

2.3.1 在脚本中执行cmd系列命令会使后续命令失效

命令【cmd /v】、【cmd /v:on】可以打开扩展变量环境(延迟变量环境);命令【cmd /e】、【cmd /e:on】可以打开命令扩展环境,虽然默认它就是打开的。

在手动创建的cmd窗口中执行命令【cmd /v:on】或【cmd /v】,会进入扩展变量环境(延迟变量环境),这时候再执行命令【exit】就能退出环境。

同理,对于命令【cmd /v:on】或【cmd /v】,也是如此。

但是,在脚本中执行这几个命令,效果会和cmd窗口中执行一样吗?

显然不会,因为脚本中有专门用来打开(或关闭)扩展变量、命令扩展的命令;例如【setlocal ENABLEEXTENSIONS】可用来在脚本中临时打开命令扩展。

为了进一步打消你的顾虑,我还是决定为你测试一下!如果我们在脚本文件执行不该执行的【cmd /v:on】或【cmd /v】、【cmd /v:on】或【cmd /v】会出现什么“妖魔鬼怪”?

在main1.bat文件中,代码如下所示。

@echo off echo main1.bat start to execute! call :end pause :end echo subprogram is executeing! exit

双击执行main1.bat,最后肯定会闪退(此情况上文已述)。 

而添加一层cmd环境(扩展变量环境),就不会闪退了。

原因倒并不是因为叠加了一层环境后,执行exit命令是退出环境;原因在于叠加了一层环境后,所有的命令都失效了,包括exit命令。 

@echo off echo main1.bat start to execute! cmd /v call :end pause :end echo subprogram is executeing! exit

 

虽然没了闪退,但是【cmd /v】后的代码全部失效,那还不如不要【cmd /v】呢!

下面进行另一种测试,这次测试call调用外部脚本程序。

main.bat的代码。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令调用demo" cmd /e:on call D:\D-desktop\demo.bat echo "在子程序中执行exit之后,主程序call下面的代码都不执行" pause

demo.bat的代码。

@echo off chcp 65001 echo "在脚本文件中,一旦进入了cmd环境,就不能再echo任何内容" echo "所以子程序的所有输出都被忽略了" echo "子程序开始执行" echo "下一条执行exit" exit echo "子程序的exit执行完了" echo "对于exit后面的代码,显然不执行了"

双击执行main.bat脚本,结果如下 。

我们显然也可以看到,只要执行了【cmd /e:on】,下面的代码都失效了。

而比较惊奇的另一点,虽然主程序最后一行的pause命令失效,但是执行bat脚本文件时也没出现闪退。

而如果把进入环境的指令去掉,就又会出现闪退问题,估计是因为exit命令又生效了。

所以,你们知道为啥我说“不要在批处理脚本中执行类似【cmd /e:on】、【cmd /v:on】的命令”了吧?因为cmd开发人员可能压根就没想着我们用户在这里用。

因为有专门的批处理脚本命令【setlocal ENABLEEXTENSIONS】和【setlocal ENABLEDELAYEDEXPANSION】。

2.3.2 在脚本内执行“setlocal系列命令”对“3条命令”无影响

(0)避雷:错误的测试方法

新建一个bat文件,代码如下。

@echo off echo main1.bat start to execute! setlocal DISABLEEXTENSIONS call :end pause :end echo subprogram is executeing! exit

双击执行,输出结果如下,没有输出子程序中的【subprogram is executeing!】,但是最后却成功执行了【pause】,说明命令【setlocal DISABLEEXTENSIONS】并没有使下面全部的代码失效。

再详细分析,可以发现其实是因为【call :end】属于扩展命令的一种,如果执行了命令【setlocal DISABLEEXTENSIONS】会关闭扩展命令,这样调用部分就失效了,也就会跳过【call :end】执行【pause】,这样就成功“说通了”。

(1)进一步测试,避开命令【setlocal ENABLEEXTENSIONS】。

为啥测试要避开这个命令?因为cmd默认就是启动命令扩展功能的,所以这个命令可能会无意义。

继续用命令【setlocal DISABLEEXTENSIONS】测试,但是需要注意尽量不用扩展命令。

新建一个main1.bat文件,代码如下。

@echo off echo "main1.bat start to execute!" setlocal DISABLEEXTENSIONS exit echo "exit is executed!"

双击执行后,直接闪退。 

可能也说明执行脚本命令【setlocal DISABLEEXTENSIONS】后,压根就没进入一种环境吧!

(1)不信邪,继续测试命令【setlocal ENABLEDELAYEDEXPANSION】。

bat文件改成如下。

@echo off echo "main1.bat start to execute!" setlocal ENABLEDELAYEDEXPANSION exit echo "exit is executed!"

双击执行后,直接闪退。 

这次,我信了!虽然没有测试命令【exit /b】、【goto :eof】,但是也不难猜出吧?

大概是因为setlocal系列的命令,在脚本内执行时,并不算是进入了一种环境,因此对3种命令【exit】、【exit /b】、【goto :eof】的影响为零。

2.3.3 在脚本内进入外部命令环境后往下语句全失效

啥是外部命令环境?

python环境、diskpart环境等,都属于外部命令环境。

(1)Python环境

新建脚本文件,代码如下。

@echo off echo "main1.bat start to execute!" python exit() echo "exit is executed!"

双击执行后结果如下,可以看出exit()语句以及下面的语句全部没有被执行。

(2)Diskpart环境

新建脚本文件,代码如下。

@echo off echo "main.bat start to execute!" diskpart exit echo "exit is executed!"

以管理员身份运行,得到结果如下,同上也是进入环境后下面的命令全部失效不被执行。

其他外部命令环境就不尝试了!

不过我们又可以回想起本文2.3.1节对一系列的cmd命令的阐述。

cmd系列命令在脚本文件中执行后,后面的命令也会失效。

说明了啥?说明这个cmd系列命令即使在脚本文件中运行,也是能进入一个环境的。

只不过在脚本文件中一旦 进入一个环境,后面的命令就仿佛“烟消云散”般消失了,直接失效。

=========================重点=============================

综上,本文的2.3节,说明了一点——“脚本文件不适合用来叠加环境”。

=========================重点=============================

三、在不叠加环境的cmd原生窗口中执行

本章节属于思维导图树中的蓝色圈圈所指情况。

3.1 执行exit时——直接退出

如果你是在cmd原生窗口中执行exit命令,意思就是说没有进入某种命令的环境,比如python环境、diskpart环境、命令扩展环境、扩展变量或延迟变量环境,那么cmd窗口会直接被关闭。

3.2 执行exit /b时——无反应

3.3 执行goto :eof时——无反应

四、在叠加环境的cmd窗口中执行 

 本章节属于思维导图树中的蓝色圈圈所指情况。

4.1 退出python环境——exit()

假如我已经进入到了python环境,然后想返回到原生cmd环境中,直接执行exit()命令即可。

如果执行exit,会出错的。 

对于命令【exit /b】和命令【goto :eof】,出错更厉害!

4.2 退出diskpart环境——exit或exit /b

假如你在cmd窗口中执行diskpart命令进入对应环境中, 而后程序会自动弹出一个关于diskpart.exe的窗口。

错误的返回原生cmd窗口的方式是单击diskpart.exe窗口右上角的“叉叉”,由于这样会导致原生Cmd窗口无法正常使用,后续只能重开。

  

正确的返回cmd原生环境的方式应该是在diskpart.exe窗口中执行exit命令。

 

对于命令【exit /b】,也是能用来退出diskpart环境的。

 命令【goto :eof】却无法退出diskpart环境。

4.3 退出命令扩展环境——exit或exit /b

当我们在原生CMD窗口中执行命令【cmd /e:on】时,标题后面就新加了一串命令文字,这其实就属于叠加了一层cmd环境(命令扩展环境)。

我们可以用exit命令来一层一层地退出cmd环境。

 

 进入扩展变量环境后,执行命令【goto :eof】没反应,说明不能用来退出环境。

进入扩展变量环境后,执行命令【exit /b】有反应(见蓝色圈圈),说明可用来退出环境。

4.4 退出延迟变量环境——exit或exit /b

在cmd原生窗口中执行命令【cmd /v:on】(或命令【cmd /v)来打开延迟变量环境,同样标题栏也会多一串命令字符。

如果要退出这层环境,也可以用exit退出。

进入扩展变量环境后,执行命令【goto :eof】没反应,说明不能用来退出环境。

进入扩展变量环境后,执行命令【exit /b】有反应(见蓝色圈圈),说明可用来退出环境。

其他的cmd环境,可以在cmd /?中查看,退出的方法都是执行命令【exit】,我就不再赘述了。

五、在批处理脚本内的主程序部分执行

本章节属于思维导图树中的蓝色圈圈所指情况。

5.1 执行exit时——直接退出

在【D:\D-desktop】目录下新建一个main.bat文件,代码如下。

@echo off chcp 65001 echo "主程序开始执行" echo "下一条指令执行exit" exit echo "下一条指令调用demo" call D:\D-desktop\demo.bat pause

同一目录,demo.bat文件的的代码如下。

@echo off echo "子程序开始执行" echo "子程序执行完了"

双击执行main.bat脚本,cmd窗口打开后闪退。

5.2 执行exit /b时——直接退出

相对于5.1来说,就只把主程序部分的【exit】改成【exit /b】。

双击执行main.bat脚本,cmd窗口打开后闪退,和【exit】效果一样。

5.3 执行goto :eof时——直接退出

相对于5.1来说,就只把主程序部分的【exit】改成【goto :eof】。

双击执行main.bat脚本,cmd窗口打开后闪退,和【exit】、【exit /b】效果一样。

六、在批处理脚本中使用Call调用程序

本节的内容实际在文章的2.2节已经讲得很详细了,不过在这里还是总结一下!

只要是用call调用的程序,在call调用程序(脚本内子程序或脚本外部程序)内执行3种命令,会有以下表现:

exit直接退出整个cmd窗口,主程序也不继续执行exit /b退出call调用程序,返回继续执行主程序goto :eof退出call调用程序,返回继续执行主程序

七、最后的总结和“3种命令”的应用场景分析

7.1 不带参数命令【exit】

不管是在主程序中执行还是子程序(批处理脚本)中执行,不管是在程序的第几层执行,都会直接导致cmd窗口的退出。

7.2 命令【goto】加上参数【:eof】

7.2.1 对参数【:eof】的补充性知识

参考来源:batch-file — GOTO:EOF返回哪里?

:EOF是预定义的标签,如Microsoft在命令 GOTO 的文档中所述。在命令提示符窗口goto /?中运行的帮助输出还说明了文件结束的特殊标签。

但是,只有默认情况下启用了命令扩展名,才支持此预定义标签。

7.2.2 命令【goto :eof】的效果小结

如果在脚本主程序中执行,就会立即退出脚本。

如果在主脚本中调用子脚本时执行,会退出子脚本而继续向下执行上一层的脚本程序。

如果在脚本内的子程序中执行,就会退出子程序而继续执行主程序。

注意它不能用来退出环境,这一点只有exit和exit /b支持。

参考来源:batch-file — GOTO:EOF返回哪里?

【goto EOF】(不带冒号)要求批处理文件中确实存在以:EOF开头的行,即文件中必须存在跳转标签EOF。

【goto :EOF】总是导致退出子例程/批处理并启用命令扩展,即使批处理文件中有一个标签EOF也是如此,因为该行以:EOF开头。

7.2.3 命令【goto :eof】的应用场景分析

有时候,我们需要在一个bat文件中调用“多个”脚本内子程序,这些子程序设置在文件的末尾。

但是有2个问题需要我们在编程时避免。

第1个,多个子程序之间需要隔离,执行完子程序最后一句后不能再向下执行到下一个子程序了;

第2个,主程序和子程序整体需要隔离,执行完主程序后,不能再向下执行子程序了。

如何避免呢?就靠的是命令【goto :eof】!

首先在主程序和子程序整体之间放一行命令【goto :eof】,然后再在每一个子程序的末尾放一个【goto :eof】;第一个【goto :eof】用来使主程序执行完时直接退出BAT脚本,而第二个【goto :eof】用来使子程序执行完时退出子程序返回到主程序的call命令的下一句继续执行。

7.3 带参数【/b】的命令【exit /b】

命令【exit /b】除了可以添加exitcode参数,以及在退出环境方面和exit效果近似、而【goto :eof】不能用来退出环境,其他与【goto :eof】可以说完全相同,也需要在命令扩展功能打开的时候使用。

换句话说,除了环境退出不能用【goto :eof】,没有附加退出代码的【exit /B】就像【goto :EOF】一样。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭