Какой самый простой способ сбросить 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. Он восстанавливает воссозданный рабочий каталог в терминале, если он был открыт до стирания.
Если это фрагмент кода, такой как "Событие после сборки" и т. Д., То вы можете добавить:
(...) || 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 определяет предоставленное значение как числовое выражение)
Я всегда просто использовал;
set ERRORLEVEL=0
Я использую это в течение многих лет осла.