Windows Batch:无法从被调用的子例程退出 - 即使goto:END也始终返回

时间:2012-03-19 14:24:02

标签: batch-file

我有一个子程序,可以调用ERRORLEVEL来检查 子例程调用其他子例程来记录消息,发送电子邮件,然后退出脚本。它转到:END,然后在调用后返回到stmt

@echo off
echo starting...
call:checkTime
echo +++ after CT
GOTO:END

:checkTime
echo the time is %TIME%
goto:END
goto:EOF

:END

2 个答案:

答案 0 :(得分:4)

问题措辞不多,但我认为我理解(​​特别是如果我专注于标题)

我对您的问题的解释:

在批处理文件的各个位置,检查ERRORLEVEL。每当检测到错误时,您都希望执行一些标准错误处理,然后退出批处理脚本。您试图创建一个子例程来执行标准处理,但子例程返回给调用者而不是退出脚本。您的问题是,如何强制您的错误处理例程退出而不是返回调用者?

<强>答案:

如果在被调用的子程序中没有发生任何错误检测,那么您可以简单地转到错误处理器而不是CALLing它。

如果您希望能够调用例程并从另一个调用的例程中退出,那么您可以继续使用CALL语句,但是使用EXIT而不是{{}来终止错误例程1}}或GOTO :EOF

回复评论的附录

是的,GOTO无法传递参数,CALLed例程将始终返回给调用者(除非例程以EXIT结束)

是的,EXIT将关闭当前的CMD shell,这通常会关闭控制台窗口。

但是......您可以让批处理文件通过另一个CMD shell执行,这样EXIT就不会关闭窗口了!

我看到的唯一潜在缺点是,一旦批处理文件(以及运行它的CMD shell)终止,环境的更改将会丢失。这对您来说可能是也可能不是问题。

GOTO :END

答案 1 :(得分:3)

是的,这是预期的行为:通过CALL命令调用的子程序可能以三种不同的方式结束:执行EXIT [/B],执行GOTO :EOF或只是到达文件的末尾。这三种方式都会导致返回调用程序。到目前为止,“GOTO命令现在接受一个目标标签:EOF,它将控制转移到当前批处理脚本文件的末尾。这是退出批处理脚本文件而不定义标签的简单方法。” (来自GOTO /?),所以第二和第三种方法都是一样的。

如果您希望有时从子程序返回,但有时需要终止调用程序,那么子程序不能通过CALL执行,而是以其他不同的方式执行。如果要将参数传递给子程序,那么它必须是一个单独的.BAT文件,它将通过带有参数和无调用的名称执行,例如:

subprogram param1 param2 ...

这样,为了让这个子程序“返回”到调用程序,它必须知道批处理文件以及它必须返回的行。该信息可以由调用程序通过变量设置;调用程序还必须确定它是以正常方式运行还是因为返回false子例程。你可以这样做:

<强> main.bat:

@echo off
rem If this is a false subroutine return: complete it
if "%1" == "return" goto %2
rem Do my usual business
rem . . .
rem Execute the subprogram as subroutine
set caller=main
set returnPoint=label23
subprogram param1 param2
:label23
rem Continue after subprogram return...

<强> subprogram.bat:

rem Do my business
rem . . .
rem To return to the caller:
%caller% return %returnPoint%
rem . . .
rem To terminate here, execute EXIT /B, GOTO :EOF, or just reach the end

抱歉,没有简单的方法可以做到这一点......