Как выполнить ветвление после проверки% ERRORLEVEL% на ветку IF-ELSE в пакетном файле, проверив две отдельные строки? - PullRequest
1 голос
/ 04 июля 2019

Пакетный файл со следующими ветвями кода в зависимости от условия %ERRORLEVEL%. set result=PASSED выполняется, если строка OK найдена в выходных данных. Пакетный файл должен также искать строку ERROR в дополнение к OK строке в выходных данных и выполнять set result=FAILED, если ERROR найден в выходных данных.

Как я могу это сделать?

rem ...
rem ...
call myCommand.cmd | FIND "OK" > NUL

if %errorlevel% == 0 (
    set result=PASSED
    set /A passedCounter=passedCounter+1
) else (
    set result=FAILED
    set /A failedCounter=failedCounter+1
)
rem ...
rem ...

1 Ответ

1 голос
/ 05 июля 2019

Этот код пакетного файла можно использовать для этой задачи.

@echo off
call myCommand.cmd | %SystemRoot%\System32\findstr.exe /I /L "OK ERROR" >"%TEMP%\%~n0.tmp" || goto Failed
%SystemRoot%\System32\findstr.exe /I /L "ERROR" "%TEMP%\%~n0.tmp" >nul && goto Failed

set "result=PASSED"
set /A passedCounter+=1
goto Done

:Failed
set "result=FAILED"
set /A failedCounter+=1

:Done
del "%TEMP%\%~n0.tmp" 2>nul
echo Result is: %result%

FINDSTR поиск в стандартном выводе пакетного файла myCommand.cmd

  • caseнечувствителен к опции I
  • и буквально к опции /L
  • для строки OK ИЛИ строка ERROR.

Символ пробела внутри строки поиска в двойных кавычках в этом случае интерпретируется как FINDSTR как ИЛИ выражение.

Код выхода FINDSTR равно 1, если не удалось найти ни OK, ни ERROR, что следует интерпретировать как сбойную операцию, поэтому обработка командного файла продолжается в командной строке ниже строки с меткой Failed.

В противном случае одна или несколько строк, содержащих OR ИЛИ ERROR, выводимые FINDSTR , записываются во временный файл в каталоге для временных файлов с именем пакетного файла в качестве имени файла ирасширение файла .tmp.

Это временный файл с оutput из первого выполненного FINDSTR снова ищется с помощью FINDSTR на этот раз поиск без учета регистра и буквально только для строки ERROR и подавление вывода путем перенаправления его на устройство NUL .

FINDSTR завершается с 0, если есть строка с ERROR, в результате чего обработка командного файла продолжается в командной строке ниже строки с меткой Failed.

В противном случае выходные данные пакетного файла myCommand.cmd содержат OK, но не ERROR, поэтому задача была успешно выполнена.

Наконец временный файл удаляется из существующего ввсе с подавлением сообщения об ошибке «не существует» путем перенаправления сообщения об ошибке на устройство NUL и результат выводится в окно консоли.

См. также:

Aдругое решение не использует временный файл:

@echo off
set "result="
for /F delims^=^ eol^= %%I in ('myCommand.cmd ^| %SystemRoot%\System32\findstr.exe /I /L "OK ERROR"') do (
    echo %%I | %SystemRoot%\System32\findstr.exe /I /L "ERROR" >nul && goto Failed
    set "result=PASSED"
)
if defined result set /A "passedCounter+=1" & goto Done

:Failed
set "result=FAILED"
set /A failedCounter+=1

:Done
echo Result is: %result%

FOR с параметром /F запускает новый процесс команды в фоновом режиме с %ComSpec% /c и командной строкой, как указано в круглых скобкахмежду двумя ', что означает с каталогом Windows на диске C: выполнение командной строки:

C:\Windows\System32\cmd.exe /c myCommand.cmd | %SystemRoot%\System32\findstr.exe /I /L "OK ERROR"

Оператор перенаправления | должен быть экранирован с помощью символа вставки ^ на Командную строку FOR следует интерпретировать как буквальный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , которая выполняет встроенную командную строку в отдельном командном процессе, запущенном в фоновом режиме.

FOR захватывает все, что выводится с помощью FINDSTR для обработки STDOUT фонового командного процесса, и обрабатывает захваченный текст построчно после запуска cmd.exeзавершается сам.

FOR будет разбивать каждую непустую строку на подстроки с использованием обычного пробела и горизонтальной табуляции в качестве разделителей строк и назначать только первую разделенную пробелом / табуляцией подстроку указанной переменной цикла I если не начинается с символа конца строки по умолчанию ;.Такое поведение разделения строк с игнорированием всей строки при запуске с точки с запятой без или с начальными пробелами / табуляциями здесь не требуется.По этой причине delims= eol= используется для определения пустого списка разделителей, чтобы отключить режим разбиения строки и определить отсутствие символа конца строки.Необходимо указывать эти две опции без использования двойных кавычек, что означает, что знаки равенства и символ пробела должны быть экранированы с помощью ^, чтобы интерпретироваться как литеральные символы, а не как разделители аргументов.

В каждой строке, выводимой FINDSTR в отдельном командном процессе, выполняется поиск строки ERROR, и, если она действительно найдена, выполнение цикла завершается с помощью перехода к командной строке под строкой с меткой Failed.В противном случае эта строка должна содержать OK, поэтому переменная окружения result теперь определяется со значением PASSED.Но может быть еще одна строка с ERROR, поэтому цикл в этом случае не завершается.

Если переменная окружения result определена после выполнения FOR , то произошелвывод строки в пакетном файле myCommand.cmd с OK и без ERROR, что означает, что задача была успешно выполнена.

Кстати: было бы намного проще, если бы пакетный файл myCommand.cmd завершился с 0 при успехе и значение больше 0 при любой ошибке.Это может быть очень легко оценено с помощью вызывающего пакетного файла.

См. Также:

Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • call /?
  • del /?
  • echo /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • set /?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...