Saltar al contenido

Establecer el nivel de error en el archivo por lotes de Windows

Este post fue evaluado por nuestros expertos para garantizar la veracidad de nuestra esta sección.

Solución:

ERRORLEVEL y %ERRORLEVEL% son dos variables diferentes. Eso significa que tu código con echo return code is %errorlevel% y if %errorlevel% NEQ 0 >>output.txt %%i, %%j, %%k probablemente esté equivocado.

ERRORLEVEL está incorporado y se usa para obtener el resultado del último comando. Puedes usarlo como:

IF ERRORLEVEL 1 ECHO error level is 1 or more

ERRORLEVELno poder estar configurado, al igual que bash no te deja set ?= ...

%ERRORLEVEL% es una variable ambiental. Si %ERRORLEVEL% está configurado, entonces se usa en su script cuando usa %ERRORLEVEL%. Si %ERRORLEVEL% no está configurado Ysi las extensiones de comando están habilitadas, entonces cae de nuevo para ERRORLEVEL. ERRORLEVEL lo hace no actualizar %ERRORLEVEL%.

Raymond Chen tiene una buena entrada de blog al respecto: ERRORLEVEL is not %ERRORLEVEL%. Parte del contenido de esta respuesta se eliminó descaradamente.

@ECHO OFF
SETLOCAL
DEL output.txt 2>nul
REM Loop through each line of input.txt
FOR /F "tokens=1-3 delims=, " %%i IN (.readyinput.txt) DO (
  ECHO.
  ECHO.
  ECHO.
  ECHO Check %%i exists, set error flag if it doesnt
  if exist .ready%%i (set "errorflag=") ELSE (set errorflag=2)
CALL echo return code is %%errorflag%%

  ECHO Run %%i if it exists
  if NOT DEFINED errorflag (
   call .ready%%i
   ECHO Move %%i to archive if no error occured
   if errorlevel 1 (SET errorflag=3) ELSE (ECHO copy .ready%%i .archive%mydate%_%mytime%_%%j_%%k_%%i)
  )
  ECHO Copy line of text to the new output.txt file if an error occured
  if DEFINED errorflag >>output.txt ECHO %%i, %%j, %%k
)
GOTO :EOF

Aquí hay un procedimiento reescrito.

Nota: output.txt se elimina al principio, de lo contrario el >> agregaría a cualquier archivo existente. 2>nul suprime los mensajes de error si la eliminación falla (por ejemplo, el archivo no existe)

Dentro de una declaración de bloque (a parenthesised series of statements)el bloque ENTERO es analizado y LUEGO ejecutado. Ninguna %var% dentro del bloque será reemplazado por el valor de esa variable EN EL MOMENTO EN QUE SE ANALIZA EL BLOQUE – antes de que se ejecute el bloque.

Por eso, IF (something) else (somethingelse) se ejecutará utilizando los valores de %variables% en el momento el IF se encuentra

Dos formas comunes de superar esto son 1) usar setlocal enabledelayedexpansion y use !var! en lugar de %var% para acceder al valor modificado de var o 2) para llamar a una subrutina para realizar un procesamiento adicional utilizando los valores modificados.

Obsérvese, por tanto, el uso de CALL ECHO %%var%% que muestra el valor modificado de var. CALL ECHO %%errorlevel%% muestra, pero lamentablemente luego RESTABLECE el nivel de error.

IF DEFINED var es true si var es ACTUALMENTE definido.

ERRORLEVEL es un nombre de variable especial. Lo establece el sistema, pero si lo establece el usuario, el valor asignado por el usuario anula el valor del sistema.

IF ERRORLEVEL n es VERDADERO si errorlevel es n O MAYOR QUE n. IF ERRORLEVEL 0 es por lo tanto siempre true.

la sintaxis SET "var=value" (donde el valor puede estar vacío) se utiliza para garantizar que los espacios perdidos al final de una línea NO se incluyan en el valor asignado.

Los comandos requeridos son simplemente ECHOed con fines de prueba. Una vez que haya verificado que los comandos son correctos, cambie ECHO COPY para COPY para copiar realmente los archivos.

Usé lo siguiente input.txt:

seterr1.bat, J1, K1
seterr5.bat,J2,K2
seterr0.bat,J3 K3
seterr5.bat, J4, K4
notexist.bat, J5, K5

Con archivos existentes seterr*.bat que contienen

@ECHO OFF
EXIT /b 1

(donde el 1 en la última línea determina el errorlevel devuelto)

y recibió la salida resultante:

Check seterr1.bat exists, set error flag if it doesnt
return code is 
Run seterr1.bat if it exists
Move seterr1.bat to archive if no error occured
Copy line of text to the new output.txt file if an error occured

Check seterr5.bat exists, set error flag if it doesnt
return code is 
Run seterr5.bat if it exists
Move seterr5.bat to archive if no error occured
Copy line of text to the new output.txt file if an error occured

Check seterr0.bat exists, set error flag if it doesnt
return code is 
Run seterr0.bat if it exists
Move seterr0.bat to archive if no error occured
copy .readyseterr0.bat .archive__J3_K3_seterr0.bat
Copy line of text to the new output.txt file if an error occured

Check seterr5.bat exists, set error flag if it doesnt
return code is 
Run seterr5.bat if it exists
Move seterr5.bat to archive if no error occured
Copy line of text to the new output.txt file if an error occured

Check notexist.bat exists, set error flag if it doesnt
return code is 2
Run notexist.bat if it exists
Copy line of text to the new output.txt file if an error occured

Tenga en cuenta que la COPIA es meramente ECHOed como mencioné anteriormente.

y salida.txt

seterr1.bat, J1, K1
seterr5.bat, J2, K2
seterr5.bat, J4, K4
notexist.bat, J5, K5

Use algo como la siguiente subrutina:

:return
   ECHO @exit /b %1 >ret.cmd
   CALL ret.cmd
   GOTO :eof

Entonces úsalo así:

:Attempt
   SETLOCAL
   CALL somethingThatFails
   SET retcode=!errorlevel!
   CALL somethingThatPasses : don't care about the errorlevel here
   CALL :return !retcode!
   ENDLOCAL
   CALL :eof

Entonces, todo se vería algo así como:

prueba.cmd…

@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION

CALL :Attempt
IF !errorlevel! NEQ 0 (ECHO Attempt Failed) ELSE (ECHO Attempt succeeded!)
GOTO :eof

:Attempt
   SETLOCAL
   CALL somethingThatFails
   SET retcode=!errorlevel!
   CALL somethingThatPasses : don't care about the errorlevel here
   CALL :return %retcode%
   ENDLOCAL
   CALL :eof

:return
   ECHO @exit /b %1 >return.cmd
   CALL ret.bat
   GOTO :eof

algo que falla.cmd…

DIR some command that fails >nul 2>&1

algo que pasa.cmd…

DIR >nul 2>&1

El único efecto secundario de esto es un archivo llamado ret.cmd. Por lo general, uso una subrutina :end que limpia y la elimina.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *