我想使用以下内容检查两个日志文件的状态。
SET/A WAITCNT=0
:WAIT
SET /a WAIT_TIME=%ADMIN_TIME%/%TIME_OUT%
IF %WAITCNT% GTR %WAIT_TIME% GOTO PROBLEM
SET/A WAITCNT=%WAITCNT%+1
TIMEOUT /T %TIME_OUT% /nobreak
FINDSTR /C:"<Running>" %HOME_1%\%LOG_FILE%
if %ERRORLEVEL%=="0" (
(
GOTO :LOG
)
ELSE GOTO WAIT
:LOG
IF %JDA_LOG_FILE%="" GOTO WWF_1
SET/A WAITCNT=0
:WAIT
SET /a WAIT_TIME=%ADMIN_TIME%/%TIME_OUT%
IF %WAITCNT% GTR %WAIT_TIME% GOTO PROBLEM
SET/A WAITCNT=%WAITCNT%+1
TIMEOUT /T %TIME_OUT% /nobreak
FINDSTR /C:"<RUNNING>" %HOME_1%\%LOG_FILE%
if "%ERRORLEVEL%"=="0" (
(
GOTO END
)
ELSE GOTO WAIT
看起来它只是在第一个if循环本身中执行,并且由于goto / call而不会进入第二个循环(我不确定)。你能帮忙吗?
答案 0 :(得分:2)
if %ERRORLEVEL%=="0" GOTO :LOG
%errorlevel%
(不带引号)应该与字符串"0"
(带引号)完全一样吗?
使用
if "%ERRORLEVEL%"=="0" GOTO :LOG
或
if %ERRORLEVEL%==0 GOTO :LOG
(除了LotPings提到的ELSE
Aready语法失败之外-如果只有一个命令,我就不会使用括号)
另一个提示:set /a
不需要百分号:set /a var=var+1
是完全有效的。还有一种增加变量的语法:
set /a var+=1
答案 1 :(得分:2)
除了代码中存在的一些语法问题(在下面列出)外,一个主要问题是您定义了两个相同的标签::WAIT
。 goto
以及call
(与标签一起使用),从当前行位置向下扫描批处理文件以查找给定的标签,当到达文件末尾时,扫描继续在文件的开头,指向当前行位置。因此,即使语法问题已解决,您也不会有两个循环;它们可能会导致两个循环。相反,第一个goto :WAIT
会跳到第二个标签:WAIT
,第二个goto :WAIT
会跳到第一个:WAIT
,这是您最不可能遇到的。< / p>
解决方案非常简单:重命名标签(或其中至少一个标签)以避免重复:
set /A WAITCNT=0
:WAIT_1
set /A WAIT_TIME=ADMIN_TIME/TIME_OUT
if %WAITCNT% gtr %WAIT_TIME% goto :PROBLEM
set /A WAITCNT+=1
timeout /T %TIME_OUT% /NOBREAK
findstr /I /C:"<Running>" "%HOME_1%\%LOG_FILE%"
if %ERRORLEVEL% equ 0 (
goto :LOG
) else (
goto :WAIT_1
)
:LOG
if "%JDA_LOG_FILE%"=="" GOTO :WWF_1
set /A WAITCNT=0
:WAIT_2
set /A WAIT_TIME=ADMIN_TIME/TIME_OUT
if %WAITCNT% gtr %WAIT_TIME% goto :PROBLEM
set /A WAITCNT+=1
timeout /T %TIME_OUT% /NOBREAK
findstr /I /C:"<Running>" "%HOME_1%\%LOG_FILE%"
if %ERRORLEVEL% equ 0 (
goto :END
) else (
goto :WAIT_2
)
语法问题:
if
/ else
结构错误;括号不平衡,并且else
必须与第一个条件命令后的右括号放在同一行,如上所示,或单行显示,例如:if %ERRORLEVEL% equ 0 (goto :LOG) else (goto :WAIT_1)
;在这种单行方法中,else
之后的命令括号是可选的,但是之前的括号是必需的; %ERRORLEVEL%
不能等于"0"
;因为我们在这里比较整数值,所以我建议取消双引号并使用运算符equ
而不是==
; %JDA_LOG_FILE%
的比较运算符为=
,尽管它应为==
;引号是错误的,%ERRORLEVEL%
也是错误的,尽管这次,在比较字符串时,需要在两边都加上引号;如果%JDA_LOG_FILE%
为空并且周围没有引号,则会引发语法错误; set /A
支持+=
运算符,可以轻松地增加变量;您也不需要%
中的变量周围的set /A
符号; findstr
的文件名参数,以免出现空格时出现错误; findstr
查找什么:
<Running>
?findstr /I /C:"<Running>" "%HOME_1%\%LOG_FILE%"
; Running
,所以要使用单词边界吗?findstr /I "\<Running\>" "%HOME_1%\%LOG_FILE%"
; /I
; 由于有两个(几乎)相同的循环,因此可以将公共部分移动到子例程中,通过call
进行调用,并提供不同的项目作为参数。为了避免在子例程中执行goto :PROBLEM
,可以让子例程返回ERRORLEVEL
,其状态决定是否需要执行goto
命令。这是一种可能的方法:
rem // Call sub-routine and provide some arguments:
call :SUB_LOOP "<Running>" "%HOME_1%\%LOG_FILE%"
rem // Detect if `ErrorLevel` is set and go to `:PROBLEM` then:
if %ERRORLEVEL% neq 0 goto :PROBLEM
:LOG
if "%JDA_LOG_FILE%"=="" GOTO :WWF_1
rem // Call sub-routine and provide some arguments:
call :SUB_LOOP "<Running>" "%HOME_1%\%LOG_FILE%"
rem // Detect if `ErrorLevel` is set and go to `:PROBLEM` then:
if %ERRORLEVEL% neq 0 goto :PROBLEM
rem // This is required to avoid the sub-routine to be executed unintentionally:
goto :EOF
:SUB_LOOP
set /A WAITCNT=0
:WAIT
set /A WAIT_TIME=ADMIN_TIME/TIME_OUT
if %WAITCNT% gtr %WAIT_TIME% (
rem // Set `ErrorLevel` to one here:
(call)
goto :EOF
)
set /A WAITCNT+=1
timeout /T %TIME_OUT% /NOBREAK
findstr /I /C:"%~1" "%~2"
if %ERRORLEVEL% neq 0 (
goto :WAIT
)
rem // `ErrorLevel` is zero at this point;
goto :EOF