Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 从嵌套批处理文件中退出_Windows_Batch File_Cmd_Call_Exit - Fatal编程技术网

Windows 从嵌套批处理文件中退出

Windows 从嵌套批处理文件中退出,windows,batch-file,cmd,call,exit,Windows,Batch File,Cmd,Call,Exit,我有4个批处理文件,假设a.bat、b.bat、c.bat和d.bat。现在这些批处理文件的调用方式是a.bat调用b.bat,b.bat调用c.call等等 如果我在任何批处理文件中遇到任何错误,我想通过说发生了错误来退出整个程序,并指出哪个批处理文件有问题。我的问题是,我该怎么做 在这里,我使用了exit/b,但它只从当前批处理文件中取出,并移回批处理文件,从中调用它: a、 球棒 b、 球棒 c、 球棒 我在批处理“C”中得到一个错误,它应该报告一个错误并退出,但不知何故它又回到了批处理“

我有4个批处理文件,假设a.bat、b.bat、c.bat和d.bat。现在这些批处理文件的调用方式是a.bat调用b.bat,b.bat调用c.call等等

如果我在任何批处理文件中遇到任何错误,我想通过说发生了错误来退出整个程序,并指出哪个批处理文件有问题。我的问题是,我该怎么做

在这里,我使用了
exit/b
,但它只从当前批处理文件中取出,并移回批处理文件,从中调用它:

a、 球棒 b、 球棒 c、 球棒 我在批处理“C”中得到一个错误,它应该报告一个错误并退出,但不知何故它又回到了批处理“B”。你知道如何从嵌套批处理文件中退出吗?

你可以试试这个(
c.bat
):


您可以使用语法错误,这会立即停止批处理,而无需关闭命令窗口

:HALT
函数调用
:\u HALT
函数仅用于抑制错误消息

c.bat

@echo off
echo this is batch 'c'
echo An error occurs
call :HALT
exit /b

:HALT
call :__halt 2> nul
exit /b

:__halt
()

您可以将ErrorLevel与退出代码一起使用,如下所述:

特别是,如果要执行手动错误,那么c.bat或b.bat应该显式地使用指定的退出代码

EXIT /b 1
(或您选择的数字),但如果您只想让windows自动错误计数,那么在运行b.bat或c.bat之后,您可以直接编写

IF ERRORLEVEL 1 EXIT /b %ERRORLEVEL%
这将把相同的错误传播到下一个程序,因此如果您愿意,它们可以立即退出。它的优点是,您可以随时停止向上传播


(编辑:为了清楚起见,这里提到的第二行代码在除底层程序外的所有程序中都是必需的,无论您使用的是手动错误还是自动错误)

jeb的致命语法错误方法可以工作,但它不能正确终止任何活动的SETLOCAL

例如,这里是fatalTest.bat:

@echo off
setlocal enableDelayedExpansion
set test=AFTER main SETLOCAL
call :sub
echo returning from main  NEVER REACHED
exit /b

:sub
setlocal
set test=AFTER sub SETLOCAL
set test
call :ExitBatch
echo returning from sub2 NEVER REACHED
exit /b


:ExitBatch
call :__exitBatch 2>nul
:__ExitBatch
for
下面是示例运行输出,演示了在批处理终止后,如何仍然定义测试和启用延迟扩展:

C:\test>fatalTest
test=AFTER sub SETLOCAL

C:\test>echo !test!
AFTER sub SETLOCAL

C:\test>
现在无法将环境恢复到批处理前状态。应终止CMD.EXE会话


这是一个改进的CtrlCTest.bat版本,可以在批处理终止时正确终止任何活动的SETLOCAL。它使用了一种令人惊讶的技术,以编程方式“按下”Ctrl-C,这是我在

您可以将:ExitBatch例程放入驻留在路径中某个位置的独立ExitBatch.bat脚本中,然后任何批处理都可以根据需要方便地调用该实用程序

@echo off
:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510

:buildYes - Establish a Yes file for the language used by the OS
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
  '"copy /-y nul ExitBatchYes.txt <nul"'
) do if not defined yes set "yes=%%Y"
echo %yes%>ExitBatchYes.txt
popd
exit /b
@echo关闭
:ExitBatch-干净地退出批处理,无论调用多少次
如果不存在“%temp%\ExitBatchYes.txt”,则调用:buildYes
电话:CtrlC nul 2>&1
:CtrlC
cmd/c出口-1073741510
:buildYes-为操作系统使用的语言建立Yes文件
pushd“%temp%”
设置“是=”
复制nul ExitBatchYes.txt>nul
对于/f“delims=(/tokens=2”%%Y in(

'"copy/-y nul ExitBatchYes.txt如果.BAT文件在take命令下,请使用CANCEL。

是的,但是OP可以调用批处理
cmd/c a.BAT
。这不会关闭窗口。但是您的窗口可以。您可以不需要额外的
:HALT
,在XP中工作,没有错误消息。我的意思是直接调用
:\uu HALT 2>nul
@endro这是很明显,我想提供一个
HALT
函数来调用,而不需要任何额外的文本+1,这是一个聪明的解决方案。但是,我相信,如果您知道自己处于失败点,脚本应该优雅地退出,并提供有意义的输出。这种聪明的技术有一个不幸的副作用-SETLOCAL没有终止在一个致命的语法错误之后。请参阅,以获得另一种更干净地终止批处理的方法。这不会打破链条。恐怕我不理解您和jeb认为他在要求什么的用例,因此,我将回答他/我/认为他在要求什么,这就是“我希望b.bat在c.bat出错后停止运行我在其中指定的其余代码,我希望a.bat对b.bat也这样做"。如果我误解了他的意思,他显然会接受你的答案,而不是我的答案。从问题:
这里我使用了exit/b,但它只从当前批处理文件中退出,并移回批处理文件,从该批处理文件被称为
。我对合理使用没有任何见解。这可能是,但超出了我的范围。适度I那不是我的部门。
IF ERRORLEVEL 1 EXIT /b %ERRORLEVEL%
@echo off
setlocal enableDelayedExpansion
set test=AFTER main SETLOCAL
call :sub
echo returning from main  NEVER REACHED
exit /b

:sub
setlocal
set test=AFTER sub SETLOCAL
set test
call :ExitBatch
echo returning from sub2 NEVER REACHED
exit /b


:ExitBatch
call :__exitBatch 2>nul
:__ExitBatch
for
C:\test>fatalTest
test=AFTER sub SETLOCAL

C:\test>echo !test!
AFTER sub SETLOCAL

C:\test>
@echo off
setlocal enableDelayedExpansion
set test=AFTER main SETLOCAL
call :sub
echo returning from main  NEVER REACHED
exit /b

:sub
setlocal
set test=AFTER sub SETLOCAL
set test
call :ExitBatch
echo returning from sub2 NEVER REACHED
exit /b


:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510

:buildYes - Establish a Yes file for the language used by the OS
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
  '"copy /-y nul ExitBatchYes.txt <nul"'
) do if not defined yes set "yes=%%Y"
echo %yes%>ExitBatchYes.txt
popd
exit /b
C:\test>CtrlCTest
test=AFTER sub SETLOCAL

C:\test>echo !test!
!test!

C:\test>set test
Environment variable test not defined

C:\test>
@echo off
:ExitBatch - Cleanly exit batch processing, regardless how many CALLs
if not exist "%temp%\ExitBatchYes.txt" call :buildYes
call :CtrlC <"%temp%\ExitBatchYes.txt" 1>nul 2>&1
:CtrlC
cmd /c exit -1073741510

:buildYes - Establish a Yes file for the language used by the OS
pushd "%temp%"
set "yes="
copy nul ExitBatchYes.txt >nul
for /f "delims=(/ tokens=2" %%Y in (
  '"copy /-y nul ExitBatchYes.txt <nul"'
) do if not defined yes set "yes=%%Y"
echo %yes%>ExitBatchYes.txt
popd
exit /b