Подтвердить что ты не робот

"rd" завершает работу с уровнем ошибки, установленным в 0, при ошибке при удалении и т.д.

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

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

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

Зачем? Что ты предлагаешь?

4b9b3361

Ответ 1

Вау, это второй случай, который я видел, где ERRORLEVEL не установлен должным образом! См. Перенаправление файлов в Windows и% errorlevel%.

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

rd testdir || echo The command failed!

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

rd testdir || rem
echo %errorlevel%

Я думал, что выше дает полную картину. Но затем ряд комментариев ниже продемонстрировал, что все еще существуют потенциальные проблемы при использовании /RD/S Если файл или подпапка в родительской папке заблокированы (на любом уровне в родительской папке), тогда RD/S/Q PARENT && echo removed || echo failed RD/S/Q PARENT && echo removed || echo failed выведет сообщение об ошибке, но ветка && срабатывает вместо || ветка. Очень неудачно. Если команда не выполнена из-за того, что родительская папка заблокирована, то || будет правильно стрелять и установить ERRORLEVEL.

Во всех случаях можно обнаружить сбой, поменяв stderr с stdout и FINDSTR "^" результат в FINDSTR "^". Если совпадение найдено, значит, произошла ошибка.

3>&2 2>&1 1>&3 rd /s test | findstr "^" && echo FAILED

Перестановка stderr и stdout важна, когда отсутствует /q потому что он позволяет "Вы уверены (да/нет)?" подсказка быть видимой на stderr, отдельно от сообщения об ошибке на stdout.

Ответ 2

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