2009-02-18 11 views
9

Tenemos un script por lotes que elimina los archivos (del) y los directorios (rd). ¿Alguien sabe cómo detener (fallar) la ejecución de la secuencia de comandos si falla alguna de estas instrucciones de eliminación? Podrían fallar si un archivo/directorio está bloqueado por Windows. Gracias.Cómo detener el script por lotes en falla del

actualización

declaraciones que estoy usando:

Del: del *.* /S /Q

RD: FOR /D %%G in (*) DO RD /s /q %%G

Respuesta

12

Para eliminar el archivo s, primero puede intentar ren (cambiar el nombre) del archivo. ren configurará ERRORLEVEL en 1 si el archivo está bloqueado. Agrega citas alrededor del nombre del archivo.

@echo OFF 

:: Delete all files, but exit if a file is locked. 
for %%F in (*.*) do (
    @echo Deleting %%F 
    ren "%%F" tmp 2> nul 
    if ERRORLEVEL 1 (
     @echo Cannot delete %%F, it is locked. 
     exit /b 1 
    ) 
    del tmp 
) 

que sospecha que puede ser capaz de hacer lo mismo para los directorios, pero me parece que no puede encontrar la manera de obtener un directorio con llave para que pueda probar. Lo siguiente puede funcionar:

:: Remove all directories, but exit if one is locked. 
FOR /D %%G in (*) DO (
    @echo Removing %%G 
    ren "%%G" tmpdir 2> nul 
    if ERRORLEVEL 1 (
     @echo Cannot remove %%G, it is locked 
     exit /b 1 
    ) 
    RD /s /q tmpdir 
) 
+1

Esto no funciona para ejecutar el archivo de imagen de proceso. Cuando inicias 'notepad.exe' puedes cambiarle el nombre correctamente, pero no puedes borrar su archivo de imagen. Lo mismo para archivos DLL cargados. – wqw

+1

Puede obtener un directorio bloqueado abriendo una ventana de cmd en él ... –

3

EDIT: Derecho, por lo del no establece la ERRORLEVEL correctamente. Ver ERRORLEVEL on DEL y Windows delete command can fail silently

ANTERIOR (incorrecta) SOLUCIÓN

debe comprobar el errorlevel.

Por ejemplo:

del file.txt 
if errorlevel 1 goto FAIL 
:PASS 
echo Worked! 
goto :END 

:FAIL 
echo Failed! 
exit /B 1 

:END 
+0

no parece funcionar: C: \> test.bat C: \> del boo.doc boo.doc. El proceso no puede acceder al archivo porque lo está usando otro proceso. C: \> if errorlevel 1 goto FAIL C: \> echo ¡Funcionó! ¡Funcionó! C: \> echo Falló! Falló! C: \> exit/B 1 –

6

DEL no devuelve un nivel de error si el archivo está bloqueado. Acabo de hacer una prueba con el archivo Excel y vi un cero (en Windows XP).

Podría ser mejor utilizar IF EXIST para eliminar el archivo después de eliminarlo.

del file.txt 
if exist file.txt ECHO "FAIL" 

DESPUÉS DE EDITAR de responsabilidad: No tengo idea de cómo se lleva a cabo ...

Se podría hacer esto para los archivos

DIR /B /S /A-d > c:\filestodelete.txt 

del *.* /S /Q  

FOR /F %%i in (c:\filestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS 
) 

luego por los directorios

DIR /B /S /Ad > c:\directoriestodelete.txt 

FOR /D %%G in (*) DO RD /s /q %%G  

FOR /F %%i in (c:\directoriestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS 
) 
+0

Buena sugerencia, excepto que estoy eliminando varios archivos (ver publicación editada) por lo que es difícil hacer la declaración existente para cada directorio/archivo. –

+0

@Marcus Leon - Creo que lo que agregué debería funcionar para su caso general ... –

1

Esta es mi forma preferida de verificar errores mientras borro archivos. Redirigimos el "resultado de error" (archivo estándar "2") a un archivo (por ejemplo, delCmd.err). Luego usamos el comando FOR como una manera de obtener acceso al operador de ~ z "tamaño de archivo". Si el tamaño del archivo de salida no es 0, entonces sabemos que "del" recibió un error ... mostramos el error con el comando "tipo" y salimos del archivo por lotes con un código de error distinto de cero:

del unwanted.txt 2> delCmd.err 
FOR /F "usebackq" %%A IN ('delCmd.err') DO set size=%%~zA 
if not "%size%"=="0" (
    echo Error deleting unwanted.txt 
    type delCmd.err 
    exit /B 1 
) 
+0

+1, Doh! ¡Tan sencillo! – dbenham

1

Aquí hay una versión más corta de la variante de monitoreo de resultados.Esto está usando el truco 2>&1 para redirigir stderr a stdout y for /f para verificar cualquier salida.

@echo off 
setlocal 
set error=0 
for /f %%i in ('del notepad2.exe 2^>^&1') do set error=1 
echo %error% 
0

Hay un script que funcionará como un amuleto. Prueba el error de eliminación probando la existencia del archivo/directorio supuestamente eliminado.

La salida será un c: \ mydirectorio existente con contenido completamente vacío. Cualquier error rompe el proceso y se informa.

El único inconveniente es que los directorios se eliminan recursivamente, porque no hay una manera simple de comenzar a eliminar directorios comenzando con la mayoría de los directorios "sub".

@echo OFF 
set path_to_clean=c:\mydirectory 

@echo -Deleting Files 
dir /A-D /S /B %path_to_clean%\* > fileslist.txt 
for /F %%F in (fileslist.txt) do (
    @echo Deleting %%F 
    del %%F 2> nul 
    if exist %%F (
     @echo Cannot delete %%F, it is locked. 
     goto errorhandling 
    ) 
) 
del fileslist.txt 
@echo -Deleting Files done 

@echo -Deleting Directories 
dir /AD /B %path_to_clean%\* > directorieslist.txt 

for /F %%D in (directorieslist.txt) do (
    @echo Deleting %path_to_clean%\%%D 
    rmdir /S /Q %path_to_clean%\%%D 2> nul 
    if exist %path_to_clean%\%%D (
     @echo Cannot delete %path_to_clean%\%%D. This folder or one of its sub-directories is locked. 
     goto errorhandling 
    ) 
) 
del directorieslist.txt 
@echo -Deleting Directories done 

:errorhandling 
rem some code here 
-1

Para rd y rmdir que puede hacer

rd "some directory" || rem 

esto hará que el nivel de error correctamente - see

+0

Desafortunadamente ese truco no funciona con el comando DEL :-( – dbenham

+1

también rd no establece errorlevel para todas las condiciones de error (por ejemplo, para acceso denegado) – jhyot

-2

Hola Esto debería funcionar así

@echo off 

for /f %%i in ('del notepad2.exe 2^>^&1') do set ERRORLEVEL=1 
IF %ERRORLEVEL%=1 then exit 
+3

Debe *** NUNCA *** establecer directamente la variable ERRORLEVEL. value anulará el valor dinámico. '% ERRORLEVEL%' ya no informará el código de error devuelto de los comandos anteriores. En su lugar, se expandirá para siempre al valor que establezca. – dbenham

0

Estos parecen funcionar para mí:

RD:

FOR /D %d IN (*) DO (RD /S /Q "%d" & IF EXIST "%d" EXIT /B 1) 

DEL:

FOR %f IN (*.*) DO (DEL /Q "%f" & IF EXIST "%f" EXIT /B 1) 

ni idea sobre el rendimiento sin embargo.

Puede agregar flag/F a DEL para un modo "force delete".

1

Solo para su información. El comando DEL hace devuelve un código de error si se produce un error grave, sin embargo, su comportamiento va más allá de nuestra intuición de que la gente simplemente creería que el código de error no funciona en absoluto.

Esto es lo que he probado en el comando DEL en Windows 7:

  • eliminación exitosa de todos los archivos: 0 (por supuesto)
  • Algunos archivos borrados, algunos archivos que faltan: 0 (la intuición espera 1)
  • fracaso Supresión debido a ningún permiso o una de sólo lectura medio: 0 (intuición espera ≥ 1)
  • unidad inexistente o conducir no preparado (por ejemplo falta CD en una unidad de CD-ROM): 1 (sí, lo obtienes, pero esperaré un código de error más alto)
  • Ruta no válida: 1 (Voy a esperar un código de error más alta, también)

Y, si se especifica una lista de archivos de comando DEL, donde al menos uno de los archivos se ajustan a la última dos tipos de error mencionados anteriormente, luego ninguno de los archivos en la lista se eliminará en absoluto.

Cuestiones relacionadas