Какой самый простой способ сбросить ERRORLEVEL на ноль?

У меня есть событие после сборки, которое запускает некоторые команды для проекта aC#. Последняя команда иногда приводит к тому, что значение ERRORLEVEL не равно нулю, и сборка завершается неудачно.

Я хочу добавить дополнительную строку команды, чтобы всегда устанавливать значение ERRORLEVEL в ноль. Какой самый удобный способ сделать это?

14 ответов

Решение

Я обнаружил, что "выход 0" выглядит как хороший способ справиться с этой проблемой.

Пример использования:

NET STOP UnderDevService / Y

выход 0

если служба UnderDevService не запущена.

Если вы используете exit /b 0 Вы можете вернуть errorlevel 0 из дочернего пакетного сценария, не выходя из родительского сценария.

Кажется, чтобы сделать трюк:

ver > nul

Не все работает, и не понятно почему. Например, следующие не делают:

echo. > nul
cls > nul

В случае события до или после сборки, если код возврата исполняемого файла больше нуля и вызов исполняемого файла не является последней строкой события до или после сборки, можно быстро отключить его и избежать запуск проверки на ненулевое errorlevel должен следовать за ошибочной строкой строкой, которая явно возвращает ноль:

cmd /c "exit /b 0"

По сути, это общая комбинация ранее упомянутых решений, которая будет работать не только с последней строкой события до или после сборки.

Я лично использую это:

cd .

Работает даже в Unix Shell.

Но этот может быть немного быстрее:

type nul>nul

Так как Process Monitor шоу QueryDirectory призывает cd .

PS:cd . есть еще один приятный побочный эффект в оболочке Unix. Он восстанавливает воссозданный рабочий каталог в терминале, если он был открыт до стирания.

Я использую VERIFY или же VERIFY > nul

Если это фрагмент кода, такой как "Событие после сборки" и т. Д., То вы можете добавить:

(...) || ver > nul

в конце последней команды.

альтернативно

cmd /c "exit /b 0"

очень чистый и не идиоматичный - читатель, который знает оболочку Windows, будет знать, что происходит, и каковы были ваши намерения.

Однако, если вы находитесь в пакетном скрипте, вы можете использовать подпрограммы, которые являются облегченным эквивалентом "дочернего пакетного скрипта" из ответа akf.

Есть подпрограмма:

:reset_error
exit /b 0

а потом просто

call :reset_error

везде, где вам это нужно.

Вот полный пример:

@echo off
rem *** main ***

call :raise_error
echo After :raise_error ERRORLEVEL = %ERRORLEVEL%

call :empty
echo After :empty ERRORLEVEL = %ERRORLEVEL%

call :reset_error
echo After :reset_error ERRORLEVEL = %ERRORLEVEL%

:: this is needed at the end of the main body of the script
goto:eof

rem *** subroutines ***

:empty
goto:eof

:raise_error
exit /b 1

:reset_error
exit /b 0

Какие выводы:

After :raise_error ERRORLEVEL = 1
After :empty ERRORLEVEL = 1
After :reset_error ERRORLEVEL = 0

Как видите - просто позвонить и вернуться через goto: eof недостаточно.

Следующее работает в современных системах Windows (на базе NT), в которых есть cmd.exe:

       rem /* This clears `ErrorLevel`; the SPACE can actually be replaced by an
rem    arbitrary sequence of SPACE, TAB, `,`, `;`, `=`, NBSP, VTAB, FF: */
(call )

SPACE(Или более точно, произвольная последовательность из одного или нескольких стандартных маркеров сепараторов, которые SPACE(код 0x20), TAB(код 0x09), ,, ;, =, NBSP(код 0xFF), VTAB(код 0x0B) и FF(код 0x0C)) является обязательным; если вы его опустите ErrorLevel вместо этого устанавливается:

       rem // This sets `ErrorLevel` to `1`:
(call)

На сайте DosTips.com есть хорошая ветка, в которой появилась эта техника.


Вот альтернативный метод, но он обращается к файловой системе и поэтому может быть немного медленнее:

       dir > nul

rem /* Perhaps this is a little faster as a specific file is given rather 
rem    than just the current directory (`.` implicitly) like above: */
dir /B "%ComSpec%" > nul

Вот некоторые другие способы сброса ErrorLevel состояния, которые даже работают в MS-DOS (по крайней мере, для версии 6.22):

more < nul > nul

rem // The `> nul` part can be omitted in Windows but is needed in MS-DOS to avoid a line-break to be returned:
sort < nul > nul

Следующие методы работают только в MS-DOS:

command /? > nul

fc nul nul > nul

Для полноты картины это устанавливает ErrorLevel состояние для 1, действительно для Windows и MS-DOS:

< nul find ""

Изучив все другие ответы, я решил найти наиболее эффективный способ сброса УРОВНЯ ОШИБКИ. Я сделал быстрый скрипт, который записал время для выполнения каждого из них:

"cmd /c "exit /b 0"", "cd .", "ver", "type nul", and "VERIFY"

вот результат:

cmd /v:on /c set ^"q=^"^ "& timeit.cmd" cmd /c ^!q^!exit /b 0^!q^! "" cd. "ver" "type nul" "ПРОВЕРИТЬ"

cmd / c "exit / b 0" занял 0: 0: 0,02 (всего 0,02 с)

CD. взято 0:0:0.00 (всего 0.00 с)

Microsoft Windows [Версия 10.0.18362.836]

вер взял 0:0:0.00 (всего 0.00 сек)

type nul занял 0:0:0.00 (всего 0.00 с)

VERIFY выключен. VERIFY занял 0: 0: 0,00 (всего 0,00 с)


Это заняло 0: 0: 0,06 (всего 0,06 с)

после просмотра с Measure-Command {command} в Powershell я обнаружил, что он действительно принимает только cd . а также cmd /c "exit /b 0" --Я делаю что-то неправильно?

Я бы рекомендовал либо cd . или type nul поскольку они не имеют ни следа на выходе консоли, ни в какой мере не медленные.

да, мне довольно скучно

Добавлять >nul после каждой команды, которая может потерпеть неудачу - это предотвращает сбой сборки.

Вы все еще можете проверить результат команды, изучив %errorlevel%,

Например:

findstr "foo" c:\temp.txt>nul & if %errorlevel% EQU 0 (echo found it) else (echo didn't find it)

Перепробовал все вышеперечисленные решения - ничего не помогло. Но нашел это решение, которое работает для меня внутри командного файла:

      set /A errorlevel=0

(переключатель /A определяет предоставленное значение как числовое выражение)

Я использую это:

ping localhost -n 1> null

Я всегда просто использовал;

set ERRORLEVEL=0

Я использую это в течение многих лет осла.

Другие вопросы по тегам