2012-06-21 1 views
11

Я пишу сценарий партии (.bat), и мне нужно обработать случай, в котором происходит сбой в удалении папки. Я использую %errorlevel% поймать код завершения, но в случае rd команды это, похоже, не работает:пакет: код выхода для «rd» также равен 0 при ошибке

C:\Users\edo\Desktop>rd testdir 
Directory is not empty 

C:\Users\edo\Desktop>echo %errorlevel% 
0 

Почему? Что ты предлагаешь?
Спасибо!

ответ

20

Вау, это второй случай, когда я видел, где ERRORLEVEL установлен неправильно! См. File redirection in Windows and %errorlevel%.

Решение такое же, как и для обнаружения отказа перенаправления. Используйте оператор ||, чтобы принять меры при сбое.

rd testdir || echo The command failed! 

Странная вещь, когда вы используете оператор ||, то ERRORLEVEL затем правильно установить до 145, если папка не была пуста, или 2, если папка не существует. Поэтому вам даже не нужно ничего делать. Вы можете условно «выполнить» замечание, и уровень ошибок будет установлен правильно.

rd testdir || rem 
echo %errorlevel% 

Обновление 2016-01-21

В апреле 2015 года Андреас Vergison заявил в комментарии, что || не ставил ERRORLEVEL для "Access Denied", или»... В Использовать ... ". В то время у меня была Windows 7, и я не думаю, что я подтвердил его претензии, но просто предположил, что он прав. Но я недавно тестировал в Windows 10, а || всегда устанавливает ERRORLEVEL в ненулевое значение при ошибке. Обратите внимание, что (call) - это тайный способ принуждения ERRORLEVEL к 0, прежде чем запускать каждую команду. Также обратите внимание, что мой сеанс cmd.exe имеет задержанное расширение.

C:\test>(call) & rd junk && echo OK || echo ERROR !errorlevel! 
Access is denied. 
ERROR 5 

C:\test>(call) & rd test && echo OK || echo ERROR !errorlevel! 
The directory is not empty. 
ERROR 145 

C:\test>(call) & rd \test && echo OK || echo ERROR !errorlevel! 
The process cannot access the file because it is being used by another process. 
ERROR 32 

C:\test>(call) & rd notExists && echo OK || echo ERROR !errorlevel! 
The system cannot find the file specified. 
ERROR 2 
+0

Ну, это просто сработало. Я полагаю, что проблема связана с '% errorlevel%' и не имеет ничего общего с 'rd'. Я думаю, что я должен переписать мои обработчики ошибок, используя эту структуру для более детерминированного поведения. Благодаря! – etuardu

+3

Это отлично работает для кодов 2 и 145, но в случае «Доступ запрещен» или «Процесс не может получить доступ к файлу, потому что он используется другим процессом», то он просто оставляет ERRORLEVEL неизменным. :( –

+0

@AndreasVergison - Спасибо! Я обновил свой ответ с вашей информацией. – dbenham

3

rd не установлен errorlevel нулю - он оставляет нетронутыми errorlevel: F.E. если предыдущая операция заканчивается положительной errorlevel и rd успешно заканчивается, она оставляет errorlevel без изменений. Пример: уровни погрешности robocopy ниже 4 являются предупреждения и не ошибками и могут быть проигнорированы, так что следующий код может закончиться с ошибкой даже если каталог был успешно удален:

robocopy ... 
if errorlevel 4 goto :error 
rd somedir 
if errorlevel 1 goto :error 

Решения: игнорировать ошибку и проверить, если каталог все еще существует после rd:

rd somedir 
if exist somedir goto :error 
+1

Также о 'robocopy': обязательно ** не **, чтобы сбросить уровень ошибок с помощью' set errorlevel = 0' после проверки, что это не> = 4, потому что эта команда создает переменную среды, которая постоянно перезаписывает внутреннюю Равно. Прочитайте [здесь] (http://blogs.msdn.com/b/oldnewthing/archive/2008/09/26/8965755.aspx) – rychu