批处理命令--call、start、goto的区别

批处理命令——call 、 start 和 goto

一、call命令总结

【1】call命令简介

  学过汇编或C的朋友,肯定都知道call指令表示什么意思。其实,在这里它的意思也是一样的。在批处理脚本中,call命令用来从一个批处理脚本中调用另一个批处理脚本。

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

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

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

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

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

【2】call命令应用

  1. 基本应用。应用示例:新建两个文本文件,一个命名为call1,修改文件的类型为bat,用Notepad++打开编辑内容为:

1 echo running call1

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

复制代码
1 @echo off
2 echo start
3 call call1.bat
4 echo running call2
5 echo end
6 pause
复制代码

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

  过程解析:

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

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

  2. 调用标签。应用示例:新建两个文本文件,一个命名为call3,修改文件的类型为bat,用Notepad++打开编辑内容为:

复制代码
1 @echo off
2 call :label
3 echo 1
4 echo 2
5 
6 :label
7 echo 3
8 echo 4
复制代码

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

1 @echo off
2 call call3.bat
3 pause

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

  过程解析:

  看到这个结果什么感觉?让你想起了什么呢?想不起来啥?一看你若有所茫的样子,就知道你把goto与这个搞混了!请看下文call命令与goto命令的区别。

  3. 调用带参数的批处理。应用示例:新建两个文本文件,一个命名为call7,修改文件的类型为bat,用Notepad++打开编辑内容为:

1 echo %1 %2
2 echo %3

  另一个命名为call8,修改文件类型为bat,用Notepad++打开编辑内容为:

1 @echo off
2 call call7.bat hello world 123
3 dir c:\
4 pause

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

【3】call命令与goto命令的区别

  call命令的应用示例2中,我们看到了call命令对跳转标签的调用,注意调用时必须在标签名前加冒号,而goto是直接跟标签名。

  关于goto命令不懂的可以参见同系列随笔《批处理命令——goto 和 :》

  同上例,我们再看看goto的执行效果:新建两个文本文件,一个命名为call5,修改文件的类型为bat,用Notepad++打开编辑内容为:

复制代码
1 @echo off
2 goto label
3 echo 1
4 echo 2
5 
6 :label
7 echo 3
8 echo 4
复制代码

  另一个命名为call6,修改文件类型为bat,用Notepad++打开编辑内容为:

1 @echo off
2 call call5.bat
3 pause

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

二、start命令总结

【1】start命令简介

  start命令比较复杂。查看其帮助文档的步骤如下:

  1. 同时按下“Win + R”键(或者桌面开始-->开始-->运行),打开“运行”窗口,输入“cmd”-->确定。

  2. 在打开的命令提示符窗口里,输入start/?-->回车,查看“start”命令的参数和用法说明(注:按任意键可以查看更多后面的内容)示例截图如下:

  3. 命令提示符窗口里,按自己的使用需要,输入-->start /具体参数-->回车,即可按自己的需要、在Windows系统里使用“start”命令

【2】start命令应用

  1.基本应用。打开系统计算器以及记事本。

  新建一个文本文件,命名为start1,修改文件类型为bat,用Notepad++打开编辑内容为:

1 start calc
2 start notepad
3 exit

  执行结果:分别打开计算器和记事本,同时终端一闪而过(因为最后exit)。

【3】start命令与call命令的区别

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

复制代码
1 @echo off
2 set a=1
3 pause>nul
4 echo start startchild.bat
5 start startchild.bat
6 echo end start
7 pause>nul
8 echo %b%
9 pause>nul
复制代码

  一个命名为startchild,修改文件类型为bat,用Notepad++打开编辑内容为:

1  @echo off
2 echo %a%
3 set b=20
4 pause>nul

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

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

复制代码
1 @echo off
2 set a=1
3 pause>nul
4 echo call callchild.bat
5 call callchild.bat
6 echo end call
7 pause>nul
8 echo %b%
9 pause>nul
复制代码

  一个命名为callchild,修改文件类型为bat,用Notepad++打开编辑内容为:

1  @echo off
2 echo %a%
3 set b=20
4 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命令的时候,建议要使用与原批处理中不同的标签名来跳转,否则可能会跳转到原批处理中而不能保证完整的执行被调用批处理中的所有语句。

 

 

出处:https://www.cnblogs.com/Braveliu/p/5078283.html

=======================================================================================

批处理命令--call、start、goto

1、call命令

CALL从一个批处理程序调用另一个批处理程序,并且不终止父批处理程序。call命令主要有2种用法,一种是调用其他批处理程序(*.bat,*.exe,*.cmd,*.COM),目前常用的是*.exe文件和*.bat文件;另一种是CALL :label arguments

C:\Users\Administrator>help call
从批处理程序调用另一个批处理程序。
 
CALL [drive:][path]filename [batch-parameters]
 
  batch-parameters   指定批处理程序所需的命令行信息。
 
如果命令扩展被启用,CALL 会如下改变:
 
CALL 命令现在将卷标当作 CALL 的目标接受。语法是:
 
    CALL:label arguments
 
一个新的批文件上下文由指定的参数所创建,控制在卷标被指定后传递到语句。您必须通过达到批脚本文件末两次来 "exit" 两次。第一次读到文件末时,控制会回到 CALL 语句的紧后面。第二次会退出批脚本。键入GOTO /?,参看 GOTO :EOF 扩展的描述,此描述允许您从一个批脚本返回。
 
另外,批脚本文本参数参照(%0%1、等等)已如下改变:
 
 
     批脚本里的 %* 指出所有的参数(如 %1 %2 %3 %4 %5 ...)
     批参数(%n)的替代已被增强。您可以使用以下语法:
 
         %~1         - 删除引号("),扩展 %1
         %~f1        - 将 %1 扩展到一个完全合格的路径名
         %~d1        - 仅将 %1 扩展到一个驱动器号
         %~p1        - 仅将 %1 扩展到一个路径
         %~n1        - 仅将 %1 扩展到一个文件名
         %~x1        - 仅将 %1 扩展到一个文件扩展名
         %~s1        - 扩展的路径只含有短名
         %~a1        - 将 %1 扩展到文件属性
         %~t1        - 将 %1 扩展到文件的日期/时间
         %~z1        - 将 %1 扩展到文件的大小
         %~$PATH:1   - 查找列在 PATH 环境变量的目录,并将 %1
                       扩展到找到的第一个完全合格的名称。如果
                       环境变量名未被定义,或者没有找到文件,
                       此修改符会扩展到空字符串
    可以组合修改符来取得多重结果:
        %~dp1       - 只将 %1 扩展到驱动器号和路径
        %~nx1       - 只将 %1 扩展到文件名和扩展名
        %~dp$PATH:1 - 在列在 PATH 环境变量中的目录里查找 %1,
                      并扩展到找到的第一个文件的驱动器号和路径。
        %~ftza1     - 将 %1 扩展到类似 DIR 的输出行。
    在上面的例子中,%1 和 PATH 可以被其他有效数值替换。
    %~ 语法被一个有效参数号码终止。%~ 修定符不能跟 %* 使用

 

1.1调用批处理

命令格式CALL [drive:][path]filename [batch-parameters]

创建文件test.bat 调用文件call.bat

@echo off
set a=环境变量
call call.bat hi hello
pause
exit /b 0

call.bat

::call.bat
echo %1
echo %2
echo %a%

 

运行结果如下:

 

注意:

 1、只在test.bat中使用命令@echo off,call.bat中也没有回显命令;

 2、在test.bat中设置环境变量,call.bat中可使用该变量

1.2调用目标标签

注意:

1、调用标签时需要“:”

2、调用标签后继续处理后面命令

实例一

@echo off
call :interCall hi hello
echo 下一步
pause
exit /b 0
 
:intercall
echo %1
echo %2

 

运行结果:

 

实例二

@echo off
call :interCall
echo 下一步
:intercall
echo hi
echo hello
PAUSE
exit /b 0 

运行结果:

2、调用call 和不用call 的区别

1、使用call 不终止父处理进程,不用call 调用批处理后,父处理进程终止,不再处理后续命令

rem test.bat
@echo off
set a=环境变量
call call.bat hi hello
echo 下一步
pause
exit /b 0

call.bat

rem call.bat
echo %1
echo %2
echo %a%
pause

 

2.2去掉call call.bat hi hello中的call运行结果如下:

3、goto 命令

 帮助文档如下

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

3.1 goto 后面不需要":",直接加label 

3.2 goto 跳至指定label后,不会处理被跳过的命令语句 

@echo off
goto interCall
echo 下一步
:intercall
echo hi
echo hello
PAUSE
exit /b 0

 

运行结果:并没有处理“echo 下一步”该语句

 

4、start类似于创建一个线程

C:\Users\Administrator>help start
启动一个单独的窗口运行指定的程序或命令。
 
START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
      [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
      [/NODE <NUMA node>] [/AFFINITY <hex affinity mask>] [/WAIT] [/B]
      [command/program] [parameters]
 
    "title"     在窗口标题栏中显示的标题。
    path        启动目录。
    B           启动应用程序,但不创建新窗口。应用程序已忽略 ^C 处理。
                除非应用程序启用 ^C 处理,否则 ^Break 是唯一可以中断
                该应用程序的方式。
    I           新的环境将是传递给 cmd.exe 的原始环境,而不是当前环境。
 
    MIN         以最小化方式启动窗口。
    MAX         以最大化方式启动窗口。
    SEPARATE    在单独的内存空间中启动 16 位 Windows 程序。
    SHARED      在共享内存空间中启动 16 位 Windows 程序。
    LOW         在 IDLE 优先级类中启动应用程序。
    NORMAL      在 NORMAL 优先级类中启动应用程序。
    HIGH        在 HIGH 优先级类中启动应用程序。
    REALTIME    在 REALTIME 优先级类中启动应用程序。
    ABOVENORMAL 在 ABOVENORMAL 优先级类中启动应用程序。
    BELOWNORMAL 在 BELOWNORMAL 优先级类中启动应用程序。
    NODE        将首选非一致性内存结构 (NUMA) 节点指定为十进制整数。
    AFFINITY    将处理器关联掩码指定为十六进制数字。进程被限制在这些
                处理器上运行。
 
                当 /AFFINITY 和 /NODE 结合时,会对关联掩码进行不同的解释。
                指定关联掩码,正如 NUMA 节点的处理器掩码正确移动到零位
                起始位置一样。进程被限制在指定关联掩码和 NUMA 节点之间的
                那些通用处理器上运行。如果没有通用处理器,则进程被限制在
                指定的 NUMA 节点上运行。
    WAIT        启动应用程序并等待它终止。
    command/program
                如果它是内部 cmd 命令或批文件,则该命令处理器是使用
                cmd.exe 的 /K 开关运行的。这表示运行该命令之后,该窗口
                将仍然存在。
 
                如果它不是内部 cmd 命令或批文件,则它就是一个程序,并将
                作为一个窗口化应用程序或控制台应用程序运行。
 
    parameters  这些是传递给 command/program 的参数。
 
注意: 在 64 位平台上不支持 SEPARATE 和 SHARED 选项。
 
通过指定 /NODE,可按照利用 NUMA 系统中的内存区域的方式创建进程。例如,可以创建两个完全通过共享内存互相通信的进程以共享相同的首选 NUMA 节点,从而最大限度地减少内存延迟。如有可能,它们即会分配来自相同 NUMA 节点的内存,并且会在指定节点之外的处理器上自由运行。
 
    启动 /NODE 1 application1.exe
    启动 /NODE 1 application2.exe
 
这两个进程可被进一步限制在相同 NUMA 节点内的指定处理器上运行。在以下示例中, application1 在节点的两个低顺序处理器上运行,而 application2在该节点的其后两个处理器上运行。该示例假定指定节点至少具有四个逻辑处理器。请注意,节点号可更改为该计算机的任何有效节点号,而无需更改关联掩码。
 
    启动 /NODE 1 /AFFINITY 0x3 application1.exe
    启动 /NODE 1 /AFFINITY 0xc application2.exe
 
如果命令扩展被启用,通过命令行或 START 命令的外部命令调用会如下改变:
 
将文件名作为命令键入,非可执行文件可以通过文件关联调用。
    (例如,WORD.DOC 会调用跟 .DOC 文件扩展名关联的应用程序)。
    关于如何从命令脚本内部创建这些关联,请参阅 ASSOC 和FTYPE 命令。
 
执行的应用程序是 32-位 GUI 应用程序时,CMD.EXE 不等应用程序终止就返回命令提示符。如果在命令脚本内执行,该新行为则不会发生。
 
如果执行的命令行的第一个符号是不带扩展名或路径修饰符的字符串 "CMD","CMD" 会被 COMSPEC 变量的数值所替换。这防止从当前目录提取 CMD.EXE。
 
如果执行的命令行的第一个符号没有扩展名,CMD.EXE 会使用PATHEXT 环境变量的数值来决定要以什么顺序寻找哪些扩展名。PATHEXT 变量的默认值是:
 
        .COM;.EXE;.BAT;.CMD
 
    请注意,该语法跟 PATH 变量的一样,分号隔开不同的元素。
 
查找可执行文件时,如果没有相配的扩展名,看一看该名称是否与目录名相配。如果确实如此,START 会在那个路径上调用Explorer。如果从命令行执行,则等同于对那个路径作 CD /D。

4.1  可以和 第2段“调用call 和不用call 的区别” 代码作对比

@echo off
set a=环境变量
start call.bat hi hello
echo 下一步
pause
exit /b 0

call.bat内容如下 

rem call.bat
echo %1
echo %2
echo %a%
pause

 

运行结果

 

 

出处:https://blog.csdn.net/qq_40951833/article/details/107396031

posted on 2020-08-26 15:58  jack_Meng  阅读(1916)  评论(0编辑  收藏  举报

导航