Ignorar quando ocorrer um erro
-
21-09-2019 - |
Pergunta
eu tenho o seguinte código em lote (cmd):
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if %errorlevel%==1 (
command
SKIP
)
command
)
EDITAR:Para deixar as coisas mais claras:for /f...
procura um diretório chamado 'Exemplo' e faz um loop para procurar mais diretórios de um.o primeiro command
é um comando de exclusão, ele exclui todos os arquivos do diretório.o command
que acontece quando ocorre um erro, é um echo
comando que grava algumas informações sobre o erro em um arquivo de texto.agora o buraco skip
coisa;às vezes, os arquivos não podem ser excluídos por causa de access denied
ou this file is in use by...
.Normalmente, o que aconteceria se não houvesse um salto, apenas interromperia o comando e travaria.Então, o que eu quero fazer é evitar que isso aconteça.Alternativamente, eu quero usar algo como skip
, para que ele possa pular o arquivo e continuar de qualquer maneira.Então eu acho que esse comando precisa ser canalizado no delete
comando.
Espero que esteja claro agora.
Desde já, obrigado.
Solução
Assim?
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if not errorlevel 1 (
command-for-success
) else (
command-for-error
)
)
Outras dicas
Crie os dois arquivos de comando e execute Delex.cmd. Os arquivos e diretórios que não são excluídos serão registrados para Delex.txt. Os que estão pendurados terão uma janela Minimizada em CMD aberta que é morta após um atraso usando o ping (graças à sugestão de Doc Brown).
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
Testado com:
\example
| file1
| file2
| file3
| file4
| file5
|
\---example
file1
file2
file3
file4
file5
Quando alguém usa del
, e "acesso negado" ou "este arquivo está em uso por ..." ocorre %errorlevel%
é 0, então testando %errolevel%
é inútil. Talvez a solução simples a seguir funcione no seu caso:
for /f "delims=" %%f in ('dir /b /s Example') do (
del %%f
if exist %%f (
echo "file not deleted"
) else (
echo "file deleted"
)
)
Eu acredito que é isso que você quer
for /f "delims=" %%f in ('dir /b /s Example') do (
command
if not errorlevel 1 (
command
) else (
command
goto :eof
)
)
Talvez isso seja mais avançado do que pode ser realizado usando apenas processamento de CMD integrado. Por que não considerar o uso do host de script do Windows (VBScript/JScript) ou mesmo PowerShell? Ambos provavelmente fornecerão o nível de controle que você está solicitando.
Experimente este arquivo em lote:
@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
)
Testado com a seguinte estrutura de diretório:
folder\
|------Example\
| |-------file1 (write-protected)
| |-------file2
| |-------file3
|------deeper\
|-------Example\
|-------file4
|-------file5 (write-protected)
|-------file6
Depois de executar o arquivo em lote, apenas file1
e file5
foram deixados. Uma mensagem "Acesso é negado" foi impressa para cada arquivo protegido por gravação encontrado; Se isso ficar irritante, você redireciona a saída do arquivo em lote como script.bat > NUL
para esconder.
Então, depois que todas as respostas existentes não o satisfizeram e você absolutamente precisa pular seu arquivo em lote, farei outra tentativa:
@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
O truque é que o loop for chama uma subfunção dentro do mesmo arquivo e fornece o parâmetro necessário para ela.Esta nova chamada é executada em um novo contexto e só pode acessar as variáveis definidas após o do call :DoSomething
na ordem dada deles.
Então você tem que acessar as variáveis aqui com %1
, %2
, etc.Se você quiser sair deste contexto você tem que fazer uma goto :eof
para pular para o final do arquivo (este marcador é predefinido no modo batch e não deve ocorrer dentro do seu arquivo), o que sai do contexto e retorna ao loop for.
Depois de percorrer todo o loop, simplesmente pulamos para o :end
marcador, faça uma pequena limpeza e pronto.
A seguinte procura das extensões do arquivo que você deseja recursivamente sob a árvore do diretório "Dirname" e executa o comandostuff.bat contra esse nome de arquivo:
para /r %i em (c: dirname *. ext) do commandstuff " %i"
Commandstuff.bat se parece com isso:
@Echo off
del %1
If (% errorlevel% == 0) Goto final
:ERRO
Erro de eco excluindo %1
:FIM
ECHO END
Isso executaria commandstuff.bat para você excluir os arquivos desejados. Quando houver um erro, ele simplesmente ecoa os detalhes do arquivo e continua processando o próximo arquivo.