我正在处理一个调用其他4个批处理文件的批处理文件。如果子批处理文件返回的错误级别代码不是0,则我希望父批处理文件捕获它,发送电子邮件并退出父批处理文件。但是,一旦第一个子批处理文件被调用并以非零错误级别返回,则父批处理文件中的任何后续命令都不会运行。这是我的批处理代码:
rem ** setup so it logs itself **
set parent=%~dp0
set me=%~n0
set LOGFILE=%parent%logs\%me%.log 2>&1
if exist "%LOGFILE%" del %LOGFILE% /f /s /q
call :LOG > %LOGFILE%
exit
:LOG
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS EnableDelayedExpansion
echo ParentDir: %parent%
echo ProgramName: %me%
echo.
rem ** script variables **
set batFile1=%parent%FILE1.bat
set batFile2=%parent%FILE2.bat
set batFile3=%parent%FILE3.bat
set batFile4=%parent%FILE4.bat
set FromEmail=server@domain.com
set Recipient=adminuser@domain.com
set CCRecipient=
set Subject=Email Subject
set Message=There was an error in running nightly batch files. Please look at the logs to determine which batch file is causing a problem. \n\nAt your service\nAdmin
set Server=smtp.domain.com
set Port=25
rem ** run bat files and capture error message **
echo.
echo Start: Send Email
set Message=Debug test code
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
call %batFile1%
set exitcode=%ERRORLEVEL%
echo %exitcode%
echo.
echo Start: Send Email
set Message=Debug test code !exitcode!
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
if %exitcode% NEQ 0 (
echo.
set Message=Execution of !batFile1! failed with error message !errorcode!. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f !FromEmail! -t !Recipient! -cc !CCRecipient! -u "!Subject!" -m "!Message!" -v -s !Server!
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile2%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile2% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile3%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile3% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile4%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile4% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
EXIT /B %ERRORLEVEL%
似乎没有执行任何跟随命令call %batFile1%
出于参考目的,这是%batFile1%
退出的方式:
EXIT /B 254
,因此每次应返回%ERRORLEVEL%254。在致电batFile1之前发送的测试电子邮件效果很好。
答案 0 :(得分:0)
@echo off
setlocal EnableExtensions
rem ** setup so it logs itself **
set "parent=%~dp0"
set "me=%~n0"
set "LOGFILE=%parent%logs\%me%.log"
if exist "%LOGFILE%" del "%LOGFILE%" /f /s /q
call :LOG > "%LOGFILE%" 2>&1
exit
:LOG
setlocal
echo ParentDir: %parent%
echo ProgramName: %me%
echo.
rem ** script variables **
set batFiles="%parent%FILE1.bat" "%parent%FILE2.bat" "%parent%FILE3.bat" "%parent%FILE4.bat"
set "FromEmail=server@domain.com"
set "Recipient=adminuser@domain.com"
set "CCRecipient="
set "Subject=Email Subject"
set Message=There was an error in running nightly batch files.^
Please look at the logs to determine which batch file is causing a problem.\n\n^
At your service\n^
Admin
set "Server=smtp.domain.com"
set "Port=25"
rem ** Send email test **
echo.
echo Start: Send Email
set Message=Debug test code
c:\APPS\sendemail.exe -f "%FromEmail%" -t "%Recipient%" -cc "%CCRecipient%" -u "%Subject%" -m "%Message%" -v -s "%Server%"
rem ** run bat files and capture error message **
for %%A in (%batFiles%) do (
call :EMAIL %%A
if errorlevel 1 exit /b
)
exit /b
:EMAIL
setlocal
echo.
call "%~1"
if errorlevel 1 (
echo %errorlevel%
set "exitcode=%errorlevel%"
) else exit /b
rem ** Send email **
if "%~n1" == "FILE1" (
set "Message=Debug test code %exitcode%"
) else set Message=Execution of '%~1' failed with error message %exitcode%.^
Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f "%FromEmail%" -t "%Recipient%" -cc "%CCRecipient%" -u "%Subject%" -m "%Message%" -v -s "%Server%"
rem ** force execution to quit if check fails **
if %errorlevel% neq 0 echo Email send error message %errorlevel%.
exit /b
通过优化代码来消除重复等。 它似乎工作得更好。我可能不小心修复了它。
在使用前建议检查echo %errorlevel%
中的call
set
,否则%errorlevel%
属于set
命令。
新代码均不需要延迟扩展,因此请删除
EnableDelayedExpansion
设置。
脚本设置为一个变量,并用作文件集,
在for
循环中。
许多set variable=value
被双引号以避免
尾随空间问题。那些不是,是多行等
更好。
“发送电子邮件”代码不在标签:EMAIL
中,这有助于
合并重复的代码。它会检查名称FILE1
是否
是参数,并使用其他电子邮件匹配
您的原始代码。
如果sendemail.exe
设置了%errorlevel%
,它将结束脚本
设置为非零,稍后在for
循环中进行检查。
如果您想退出被调用的子批处理文件,
将最后一行从exit /b
更改为exit /b %exitcode%
。
请注意,exit /b
的隐式使用与exit /b %errorlevel%
相同。
如果您喜欢以后的版本,请根据自己的喜好更新代码。
如果使用后者,则可能需要延迟变量扩展
在代码块中,即(command & exit /b !errorlevel!)
。