Який найпростіший спосіб скинути ERRORLEVEL до нуля?


76

У мене є подія після збірки, яка запускає деякі команди для проекту ac #. Остання команда іноді спричиняє, що значення ERRORLEVEL не дорівнює нулю, і тоді збірка не вдається.

Я хочу додати додатковий рядок команди, щоб завжди встановлювати значення ERRORLEVEL на нуль. Який найзручніший спосіб це зробити?


Збірка насправді не провалюється, тільки IDE справді схожа на це.
Дикам

10
Я розумію, що це досить стара публікація ... Мені вдалося скинути рівень помилок до 0, видавши після останньої команди команду "type nul". Просто відчув, що це може бути корисним.
Арун

Відповіді:


70

якщо ви використовуєте, exit /b 0ви можете повернути errorlevel 0зсередини дочірній пакетний сценарій, не виходячи з батьківського.


5
З усіх запропонованих рішень це, мабуть, найкраще. Я збираюся кинути цей рядок у сценарій resetErrorlevel.bat . Загалом, той факт, що потрібно зробити так багато, щоб зробити щось таке дріб’язкове, як очищення рівня помилок сценарію, є ще одним доказом того, що за винахідником пакетного програмування Windows слід вишукувати та суворо карати. ;)
antred

55

Здається, це робить фокус:

ver > nul

Не все працює, і незрозуміло чому. Наприклад, наступне не робить:

echo. > nul
cls > nul

12
Я думаю, що причина того, чому "echo" та "cls" не працюють, полягає в тому, що це вбудовані в оболонку команди, а не реальні програми.
user95319

2
Я вам це дам, але де ver.exe?
Джейсон Кресовати,

1
У пакетному командному рядку "ver" повертає версію MS Windows, наприклад "Microsoft Windows [Версія 6.1.7601]".
AnneTheAgile

5
якщо запустити довідку в командній оболонці, ви побачите, що ver - це також вбудована команда
baye

2
@BaiyanHuang - Я майже впевнений "ver", що це внутрішня команда, але як ви можете це зробити "help"? Багато з команд , перерахованих в "help"є «зовнішніми» команди , як: Find.exe, Findstr.exe, Help.exe, Subst.exe, Wmic.exe, Xcopy.exe, ...
Кевін Fegan

32

У подіях до або після збірки, якщо код повернення виконуваного файлу більший за нуль, а виклик виконуваного файлу не є останнім рядком події до або після збірки, швидкий спосіб вимкніть його та уникайте спрацьовування перевірки на ненульове значення errorlevel- це слідування за рядком, що не спрацьовує, з рядком, який явно повертає нуль:

cmd /c "exit /b 0"

По суті, це загальна комбінація раніше згаданих рішень, яка працюватиме не лише з останнім рядком події до або після збірки.


дякую, це спрацювало для мене. простіший звук пропозиції "вихід 0" вище не вирізає його, оскільки я хочу продовжувати робити речі після скидання рівня помилок, а не виходу
madoki

4
ще більше фантазії: ви можете використовувати <some failing command> || cmd /c "exit /b 0"як одну підкладку.
Alyssa Haroldsen

Мені подобається цей метод для встановлення довільного рівня помилок, наприклад:, cmd /c "exit /b 9009"але, здається, він трохи надмірний, якщо встановити його на 0. Не буде ver > nul(внутрішня команда) працювати так само добре з меншими накладними витратами, ніж завантаження іншої копії командної оболонки cmd /c "exit /b 0"?
Кевін Феган

2
/bНе потрібно , так cmd /c “exit 0”прекрасно працює теж.
Ross Smith II

Мені подобається, що цей виконує роботу. Дякую. Одна забавна річ, коли я простежую якийсь файл, і мій рівень помилок постійно змінювався на 1, нарешті, я виявив, що підказка користувачеві like (set / p id = "enter id") змінює рівень помилок на 1! ... Я заповнив b
A Khudairy

18

Я виявив, що "вихід 0" виглядає як хороший спосіб вирішити цю проблему.

Приклад використання:

NET STOP UnderDevService / Y

вихід 0

якщо служба UnderDevService не запущена.


10
ні, якщо ви також хочете запустити цей командний файл із командного рядка, оскільки вихід 0 закриє вікно. cmd / c "exit / b 0", як пропонується нижче, набагато кращий
madoki

16

Я особисто використовую це:

cd .

Працює навіть в оболонці unix.

Але, це може бути трохи швидше:

type nul>nul

Тому що Process Monitorпоказує QueryDirectoryдзвінки наcd .

PS: cd . має ще один приємний побічний ефект в оболонці unix. Він відновлює відтворену робочу директорію в терміналі, якщо вона була відкрита перед стиранням.



7

Якщо це фрагмент типу "Подія після збірки" тощо, тоді ви будете чудово додавати:

(...) || 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 недостатньо.


2

Ось кілька інших способів скинути 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

keyb > nul

Для повноти це встановлює ErrorLevelстан 1, що діє як для Windows, так і для MS-DOS:

< nul find ""

1

Наступне працює в сучасних системах 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

0

Додайте >nulпісля кожної команди, яка, ймовірно, не вдасться - це, здається, запобігає збій.

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

Наприклад:

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

2
Це не буде працювати - оболонка оцінює весь командний рядок відразу, тому% errorlevel% буде замінено перед тим, як буде виконана команда "findstr". Замість цього використовуйте "if errorlevel 1", щоб перевірити ненульовий рівень помилок.
UveBaemayr

2
Можливо, ваш CI-сервер не виконує збірки, якщо, наприклад, знаходить рядок "помилка" у стандартному виведенні / стандартній помилці. Ви не скидаєте статус. Ви просто глушите команду. Для глибшої тиші використовуйте> нуль 2> нуль
Томаш Гандор

0

Переглянувши всі інші відповіді, я вирішив знайти, який спосіб був найбільш ефективним для скидання ERRORLEVEL. Я зробив швидкий сценарій, який записав час на виконання кожного з них:

"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 "вихід / b 0" зайняв 0: 0: 0,02 (всього 0,02 с)

компакт-диск зайняло 0: 0: 0,00 (всього 0,00 с)

Microsoft Windows [Версія 10.0.18362.836]

версія зайняла 0: 0: 0.00 (всього 0.00 с)

тип нуль взяв 0: 0: 0,00 (всього 0,00 с)

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з тих пір, і жоден з них не має сліду на виході консолі, і вони не є повільними в будь-якому вимірі.

так, мені досить нудно


Так, cmd /C exit [/B] 0має бути найповільнішим, оскільки новий cmd.exeекземпляр відкривається та закривається; інші - це все внутрішні команди, тому немає доступу до файлової системи для пошуку виконуваних файлів ...
aschipfl


-5

Я завжди просто користувався;

set ERRORLEVEL=0

Я використовую його протягом осличих років.


29
Це легко, але це дуже погана ідея, оскільки це створює змінну з іменем, errorlevelяка накладає внутрішню псевдо зміннуerrorlevel
jeb

6
Крікі, ти маєш рацію! Ого, схоже, я роками
ухиляюся
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.