考虑以下批处理文件:
@echo off
set ORACLESERVER=ORAOP09
set ORACLEDB=OraDb11g_home1
set ORACLESERVICES.1 = OracleVssWriter%ORACLESERVER%
set ORACLESERVICES.2 = OracleDBConsole%ORACLESERVER%
set ORACLESERVICES.3 = Oracle%ORACLEDB%TNSListener
set ORACLESERVICES.4 = OracleService%ORACLESERVER%
AT > NUL
IF ERRORLEVEL 1 (
echo FATAL: THIS SCRIPT MUST BE RUN AS ADMINISTRATOR!
pause
exit
)
echo Stopping services...
FOR /F "tokens=2* delims=.=" %%A IN ('SET ORACLESERVICES.') DO sc stop %%B > NUL
FOR /F "tokens=2* delims=.=" %%A IN ('SET ORACLESERVICES.') DO call:check %%B
:check
sc query %1 | find /I "State" | find /I "STOPPED"
IF ERRORLEVEL 1 call:check %1
echo All services stopped successfully!
pause
exit
在第二个FOR语句中,当ERRORLEVEL = 0时,文件的其余部分运行,而不是转到下一个FOR项。我怎样才能按预期工作?
谢谢!
答案 0 :(得分:3)
您忘记了批处理文件没有控制结构。您必须通过从批处理文件的末尾删除或通过exit /b
显式终止每个子例程。批处理文件的主体也是如此(为了避免犁入第一个子程序的主体)。
此外,您的check
子例程中的无限递归会很快耗尽cmd
的嵌套能力。使用普通goto
。
所以:
....................
FOR /F "tokens=2* delims=.=" %%A IN ('SET ORACLESERVICES.') DO call:check %%B
echo All services stopped successfully!
pause
exit
rem If you change your mind and remove the exit above, you'll need this:
goto :EOF
:check
sc query %1 | find /I "State" | find /I "STOPPED"
IF ERRORLEVEL 1 goto check
goto :EOF
rem Technically you don't need the above line when this subroutine
rem is at the end of the batch file, but it's a good idea to put it
rem in anyway for clarity and to simplify future modifications