75

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

例子:

CD:\MyFolder\MyFiles
Mybatfile.bat

Copy afile toHere

或者

CD:\MyFolder\MyFiles
CALL Mybatfile.bat

COPY afile toHere

CALL使用或START根本不使用它们有什么区别?这会对它是否返回复制命令的结果有任何影响吗?

4

4 回答 4

79

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

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

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

cmd /c "calledFile.bat"

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

我不知道有一个好的解决方案可以保证在所有情况下都返回并保持环境变化。

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

于 2013-02-06T15:15:52.493 回答
45

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

Start不一样call,它创建一个新的 cmd.exe 实例,因此它可以异步运行一个调用的批处理文件

于 2013-02-06T14:52:56.947 回答
12

`CALL' 语句是在 MS-DOS 3.3 中引入的

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

所以在你的情况下,解决方案是使用CALL

于 2013-02-06T14:55:37.930 回答
7

好吧,实际上我什至没有真正考虑过这样一个事实,即如果你调用一个批处理(不管是“类型”,即“.bat”或“.cmd”),如果你不调用它就不会返回使用通话。

尽管出于不同的原因,我一直在使用自己的电话,但实际上我很惊讶没有其他人提出。也许我错过了。也许我是世界上唯一一个知道的人!!:O

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

如果您使用 call 您可以使用二进制逻辑运算符来决定如何根据 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%
     )     

(请注意第二个“回声”之前部分中的“呼叫” ||。我相信这就是人们在当天没有延迟扩展的方式。如果您确实启用了延迟扩展(通过批处理或启动中的 setlocal EnableDelayedExpansion一个命令提示符cmd /v:on然后你可以做!ERRORLEVEL!。)

......这是我必须道歉的地方,如果你if ERRORLEVEL过去有过创伤,你应该停止阅读。我得到它。相信我。我曾考虑在 Fiverr 上付钱让某人为我远程输入此内容,但为了完整起见,我只想为团队拿一个,并提到您还可以执行以下操作来检查错误级别:

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

如果您以前从未输入过,那就太好了!您将活得更久,而无需阅读为什么您没有得到您期望的结果。残酷是您要寻找的词,而不是“古怪”。


然而,我真正想要了解的重要部分是,如果你尝试这个并且不使用“调用”,它将始终执行“真实”分支。自己试试吧!

如果我遗漏了什么,或者您知道更好的方法,请告诉我。我喜欢学习这样的东西!


我提到的附加信息:

我已经知道很长一段时间了,您可以在命令之前放置重定向,如下所示:

    >nul echo. This won't be displayed!

但前几天我无意中发现自己是个笨蛋,你显然也可以这样做:

    echo A B>file.txt C

并且真的很惊讶地发现一个file.txt由“AB C”组成的。看来你可以把它们放在任何地方,甚至在命令里面。我从来没有见过有人这样做,也没有提到过,但我见过有人提到你可以在他们前面加上一行。

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

保持书呆子!

于 2019-07-29T18:59:53.243 回答