Пропустить при возникновении ошибки
-
21-09-2019 - |
Вопрос
у меня есть следующий код в пакете (cmd):
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if %errorlevel%==1 (
command
SKIP
)
command
)
РЕДАКТИРОВАТЬ:Чтобы сделать вещи более ясными:for /f...
ищет каталог с именем «Пример» и выполняет циклический поиск большего количества каталогов, чем один.первый command
это команда удаления, она удаляет все файлы в каталоге.тот command
что происходит при возникновении ошибки, является echo
команда, которая записывает некоторую информацию об ошибке в текстовый файл.теперь дыра skip
вещь;иногда файлы не могут быть удалены из-за access denied
или this file is in use by...
.Обычно, если бы не было пропуска, команда просто останавливалась бы и зависала.Итак, что я хочу сделать, так это предотвратить это.В качестве альтернативы я хочу использовать что-то вроде skip
, поэтому он может пропустить файл и продолжить в любом случае.Поэтому я думаю, что эту команду необходимо передать в delete
команда.
Надеюсь, теперь это ясно.
Заранее спасибо.
Решение
Так?
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if not errorlevel 1 (
command-for-success
) else (
command-for-error
)
)
Другие советы
Создайте два командных файла и запустите delex.cmd.Неудаленные файлы и каталоги будут записаны в файл delex.txt.Те, которые зависают, будут иметь открытое свернутое окно cmd, которое закрывается после задержки с помощью ping (спасибо предложению Дока Брауна).
delex2.cmd
----------
@echo off
del /q %1
if exist %1 echo %1 not deleted!>>delex.txt
exit
delex.cmd
---------
@echo off
if exist delex.txt del delex.txt
for /f "delims=" %%f in ('dir /s /b example') do start "delextaskkill" /min delex2.cmd "%%f"
ping 127.0.0.1 -n 3 -w 1000> nul
taskkill /fi "Windowtitle eq delextaskkill"> nul
Протестировано с:
\example
| file1
| file2
| file3
| file4
| file5
|
\---example
file1
file2
file3
file4
file5
Когда человек использует del
, и появляется сообщение «доступ запрещен» или «этот файл используется...», %errorlevel%
равно 0, поэтому тестирование %errolevel%
бесполезно.Возможно, в вашем случае подойдет следующее простое решение:
for /f "delims=" %%f in ('dir /b /s Example') do (
del %%f
if exist %%f (
echo "file not deleted"
) else (
echo "file deleted"
)
)
Я верю, что это то, чего ты хочешь
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if not errorlevel 1 (
command
) else (
command
goto :eof
)
)
Возможно, это более сложная задача, чем можно сделать, используя только встроенную обработку cmd.Почему бы не рассмотреть возможность использования Windows Scripting Host (vbscript/jscript) или даже PowerShell?Оба, скорее всего, обеспечат вам тот уровень контроля, который вы запрашиваете.
Попробуйте этот командный файл:
@echo off
REM For each directory named 'Example' ...
for /f "delims=" %%f in ('dir /b /s Example') do (
REM .. enter the directory and delete all the files found there.
pushd .
cd %%f
del /q *
for /f "delims=" %%z in ('dir /b') do (
REM Any files that still exist must have been inaccessable. Log an error.
echo Unable to delete file %%z > C:\logfile.txt
)
popd
)
Протестировано со следующей структурой каталогов:
folder\
|------Example\
| |-------file1 (write-protected)
| |-------file2
| |-------file3
|------deeper\
|-------Example\
|-------file4
|-------file5 (write-protected)
|-------file6
После запуска командного файла только file1
и file5
были оставлены.Сообщение «Доступ запрещен» печаталось для каждого обнаруженного файла, защищенного от записи;если это раздражает, вы перенаправляете вывод командного файла, например script.bat > NUL
чтобы скрыть это.
Итак, после того, как все существующие ответы вас не удовлетворили и вам абсолютно необходимо пропустить пакетный файл, я сделаю еще одну попытку:
@echo off
setlocal
for /f "delims=" %%f in ('dir /b /s batch') do call :DoSomething %%f
goto end
:DoSomething
echo Here i am: %1
if %errorlevel%==1 goto :eof
echo No error occured
goto :eof
:end
endlocal
Хитрость в том, что цикл for вызывает подфункцию в том же файле и передает ей необходимый параметр.Этот новый вызов выполняется в новом контексте и может получить доступ только к переменным, определенным после do call :DoSomething
в данном порядке их.
Итак, вам нужно получить доступ к переменным здесь с помощью %1
, %2
, и т. д.Если вы хотите выйти из этого контекста, вам придется сделать goto :eof
для перехода в конец файла (этот маркер предопределен в пакетном режиме и не должен встречаться в вашем файле), что покидает контекст и возвращается в цикл for.
Пройдя весь цикл, мы просто переходим к :end
маркер, немного подчистим и готово.
Следующее ищет нужные расширения файлов рекурсивно в дереве каталогов «имя_каталога» и выполняет командуstuff.bat для этого имени файла:
для /r %i in (c: dirname *. ext) do commandStuff " %i"
Commandstuff.bat выглядит так:
@ЭХО ВЫКЛ.
дель %1
If (% errorlevel% == 0) goto End
:ОШИБКА
Ошибка эха при удалении %1
:КОНЕЦ
Конец эха
Это запустит команду Commandstuff.bat, чтобы вы могли удалить нужные файлы.В случае ошибки он просто выведет информацию о файле и продолжит обработку следующего файла.