要“调用”还是“不调用”批处理文件?

时间:2013-02-06 14:49:53

标签: batch-file cmd command-line call

如果从bat文件内部调用了另一个批处理文件但仍有一些剩余的操作需要完成,那么如何确保对第一个bat文件的调用将在完成或错误之后,将返回到调用它的文件在第一个实例?

示例:

CD:\MyFolder\MyFiles
Mybatfile.bat

Copy afile toHere

CD:\MyFolder\MyFiles
CALL Mybatfile.bat

COPY afile toHere

使用CALLSTART或者根本不使用它们有什么区别?这会对是否会返回复制命令的结果产生影响吗?

4 个答案:

答案 0 :(得分:52)

正如其他人所说,CALL是在.bat中调用另一个bat文件并返回给调用者的正常方法。

但是,如果CALLed批处理文件有致命的语法错误,或者如果CALLed脚本在没有/ B选项的情况下以EXIT终止,则所有批处理文件处理将停止(控制将不会返回给调用者)。

如果通过CMD命令执行第二个脚本,则可以保证控制权将返回给调用者(只要控制台窗口保持打开状态)。

cmd /c "calledFile.bat"

但是这有一个限制,即在返回时不会保留被调用批处理设置的环境变量。

我不知道在所有情况下保证退货并保持环境变化的良好解决方案。

如果您确实需要在使用CMD时保留变量,那么您可以让“被调用”脚本将变量更改写入临时文件,然后让调用者读取临时文件并重新建立变量。

答案 1 :(得分:27)

对于.bat或.cmd文件,

call是必需的,否则控件将不会返回给调用者。
对于exe文件,它不是必需的。

Startcall不同,它会创建一个新的cmd.exe实例,因此它可以异步运行名为的批处理文件

答案 2 :(得分:10)

在MS-DOS 3.3中引入了“CALL”语句

它用于调用批处理文件中的其他批处理文件,而不会中止调用批处理文件的执行,并对两个批处理文件使用相同的环境。

因此,在您的情况下,解决方案是使用CALL

答案 3 :(得分:2)

好吧,实际上,我什至没有真正考虑过以下事实:如果您调用一个批处理(无论“类型”,即“ .bat”或“ .cmd”),那么如果您调用它,它将不会返回不要使用通话。

我一直在用自己打电话,因为另一个原因,我实际上很惊讶没有人提出来。也许我错过了。也许我是世界上唯一知道的人! :O

可能不是,但是我将在这里放弃这些知识,因为它非常有用。

如果使用调用,则可以使用二进制逻辑运算符根据ERRORLEVEL结果决定如何继续。实际上,我总是对&&和||感到困惑。存在于DOS中,不能以这种方式使用。好吧,这就是为什么。

最简单的测试方法是使用记事本或在命令提示符下创建return.cmd,如下所示:

c:\> type con >return.cmd       

您现在将注意到光标下降到下一行并挂起。输入:

@exit /B %1

然后按[ENTER],然后按[CTRL]-[Z],将创建该文件。好!您现在可以随意尝试以下两个示例:

call return.cmd 0 && echo Huzzah! A Complete Success! (Or cover up...)

call return.cmd 123 || echo Oops! Something happened. You can check ERRORLEVEL if you want the tinest amount of additional information possible.

那又怎样?好了,将0和123互换后再次运行它们,您应该看到不打印消息。

也许这个多行示例会更有意义。我一直在用这个:

     call return.cmd 0 && @(
         echo Batch says it completed successfully^^!
     ) || @(
         echo Batch completed, but returned a 'falsey' value of sort.
         call echo The specific value returned was: %ERRORLEVEL%
     )     

(请注意第二个“ echo”之前||部分中的“ call”。我相信这是人们今天回避没有延迟扩展的方式。如果您确实启用了延迟扩展(通过在批处理中设置setLocal EnableDelayedExpansion或使用cmd /v:on启动命令提示符,然后就可以执行!ERRORLEVEL!。)

...这是我要道歉的地方,并说如果您过去曾遭受if ERRORLEVEL的创伤,则应该停止阅读。我知道了。相信我。我曾考虑过要在fiverr上付钱给我远程输入,但是为了完整起见,我只打算带一个团队,并提到您还可以执行以下操作来检查错误级别:

    if ERRORLEVEL 123 @echo QUICK! MOTHERS, COVER YOUR CHILDREN'S EYES! FINGERS ARE BEING UNDONE! :'(

如果您之前从未输入过,那么好!您将活得更长一些,而不必仔细阅读为何无法获得预期的结果。残酷是您要查找的词,而不是“古怪”。


但是,我真正想了解的重要部分是,如果您尝试这样做并且不使用“调用”,它将始终执行“ true”分支。自己尝试一下!

如果我缺少任何东西,或者您知道一种更好的方法,请告诉我。我喜欢学习这样的东西!


我提到的其他信息:

一段时间以来,我就知道您可以在这样的命令之前放置重定向:

    >nul echo. This won't be displayed!

但是前几天我偶然发现了一个dumdum,你显然也可以这样做:

    echo A B>file.txt C

真的很惊讶地发现一个由“ A B C”组成的file.txt。您似乎可以将它们放置在任何位置,即使在命令中也可以。我从未见过有人这样做,也从未提及。但是我见过有人提到您可以在行前加上一行。

也许这是Windows 10独有的bug。如果您有其他版本并想尝试一下,请告诉我,我会对您所发现的内容感兴趣。

保持书呆子!