Как перехватить возвращенный уровень ошибки файла подпакета и действовать соответственно - PullRequest
0 голосов
/ 02 апреля 2019

Я работаю над командным файлом, который вызывает 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, работает нормально.

1 Ответ

0 голосов
/ 03 апреля 2019
@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!).

...