2012-06-21 18 views
11

Estoy escribiendo un script por lotes (.bat) y necesito manejar el caso en el que falla la eliminación de una carpeta. Estoy usando %errorlevel% para coger el código de salida, pero en el caso del comando rd parece no trabajar:lote: El código de salida para "rd" también es 0 en caso de error

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

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

¿Por qué? ¿Que sugieres?
Gracias!

Respuesta

20

¡Guau, este es el segundo caso que he visto donde ERRORLEVEL no está configurado correctamente! Ver File redirection in Windows and %errorlevel%.

La solución es la misma que para detectar fallas de redirección. Use el operador || para tomar medidas en caso de falla.

rd testdir || echo The command failed! 

Lo extraño es que, cuando se utiliza el operador ||, ERRORLEVEL se establece a continuación correctamente a 145 si la carpeta no estaba vacía, o 2 si no existe la carpeta. Entonces ni siquiera necesitas hacer nada. Podría "ejecutar" condicionalmente una observación, y el nivel de error se establecerá correctamente.

rd testdir || rem 
echo %errorlevel% 

actualización 21/01/2016

Ya en abril de 2015, Andreas Vergison reivindican en un comentario que || no ha ajustado el ERRORLEVEL de "Acceso denegado", o" ... En Use ... "errores. Tenía Windows 7 en ese momento, y no creo que haya verificado su reclamo, pero simplemente asumí que estaba en lo cierto. Pero recientemente probé en Windows 10, y el || siempre establece el ERRORLEVEL en un valor distinto de cero por error. Tenga en cuenta que (call) es una forma arcana de forzar el ERRORLEVEL a 0 antes de ejecutar cada comando. También tenga en cuenta que mi sesión cmd.exe ha retrasado la expansión habilitada.

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

Bueno, eso funcionó. Supongo que el problema está relacionado con '% errorlevel%' y no tiene nada que ver con 'rd'. Creo que debería volver a escribir mis manejos de error usando esta estructura para un comportamiento más determinista. ¡Gracias! – etuardu

+3

Esto funciona bien para los códigos 2 y 145, pero en el caso de "Acceso denegado" o "El proceso no puede acceder al archivo porque está siendo utilizado por otro proceso", simplemente deja ERRORLEVEL sin cambios. :( –

+0

@AndreasVergison - ¡Gracias! Actualicé mi respuesta con su información. – dbenham

3

rd no se pone a cero errorlevel - que deja intacta errorlevel: F. E. si la operación anterior finaliza en positivo errorlevel y rd finaliza correctamente, deja errorlevel sin cambios. Ejemplo: niveles de error de robocopy por debajo de 4 son advertencias y no errores y pueden ser ignorados por lo que el siguiente código puede terminar con error incluso cuando el directorio se ha eliminado correctamente:

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

Solución: ignorar el error y comprobar si el directorio existe aún después de rd:

rd somedir 
if exist somedir goto :error 
+1

También sobre 'robocopy': asegúrese ** no ** para restablecer el nivel de error con' set errorlevel = 0' después de comprobar que no es> = 4 porque este comando crea una variable de entorno que sobrescribe permanentemente el interno nivel de error Lea [aquí] (http://blogs.msdn.com/b/oldnewthing/archive/2008/09/26/8965755.aspx) – rychu

Cuestiones relacionadas