HOWTO · Batch
Manejo de errores en secuencias de Batch comandos
Este tutorial verá el manejo de errores en Batch Script.
En esta página
Para gestionar errores en un archivo .bat o .cmd de Windows, comprueba inmediatamente el código de salida del comando y elige una rama que informe del problema o continúe si se ejecuta correctamente. Por convención, los comandos Batch devuelven 0 si tienen éxito y un código distinto de cero si fallan, aunque un código concreto puede identificar una condición específica. %ERRORLEVEL% muestra el estado actual, mientras que IF ERRORLEVEL comprueba si alcanza o supera un valor dado.
Cómo funcionan los niveles de error en Batch
Cuando termina, un comando devuelve un código de salida. Por convención, 0 significa que se ejecutó correctamente; un valor distinto de cero indica que no se completó con éxito, aunque su significado exacto depende del comando. Un script Batch puede usar este estado para decidir qué hacer a continuación.
Usa %ERRORLEVEL% para leer el código actual o IF ERRORLEVEL n para comprobar un umbral. IF ERRORLEVEL n es verdadero cuando el código actual es mayor o igual que n, no solo cuando es igual. Comprueba el estado justo después del comando cuyo resultado te interesa, antes de que otro comando lo reemplace.
Comprobar el código de salida de un comando
Si compruebas varios umbrales, evalúa primero el más alto; de lo contrario, un código superior también cumplirá cada umbral inferior. Para una comparación directa, guarda %ERRORLEVEL% inmediatamente después del comando y compara el valor guardado.
Este ejemplo comprueba si el valor contiene el texto ready. Cambia message por otra palabra para ver la rama de fallo. El valor guardado procede directamente de findstr, antes de que cualquier comando echo pueda reemplazarlo. El paquete proporcionado no incluye una ejecución de este ejemplo en el Símbolo del sistema de Windows.
@echo off
set "message=ready"
echo(%message%| findstr /c:"ready" >nul
set "command_status=%ERRORLEVEL%"
if "%command_status%"=="0" (
echo Match found.
) else (
echo Match not found.
)
En un bloque entre paréntesis, las referencias %variable% se expanden cuando se analiza el bloque. El estado se guarda antes de entrar en él, por lo que la comparación usa el resultado almacenado. Para comprobar un estado exacto, compara ese valor guardado; IF ERRORLEVEL n, en cambio, comprueba si el estado actual es al menos n.
Gestionar errores con comandos condicionales
Usa && para ejecutar el siguiente comando solo si el anterior tiene éxito, y || para ejecutarlo solo si el anterior falla. Estos operadores son útiles para ramas breves:
some_command && echo Success || echo Failure
Para gestionar casos más largos, un bloque IF es más fácil de leer. IF ERRORLEVEL 1 comprueba si el código es al menos 1; esto abarca los estados de fallo habituales, distintos de cero, pero no distingue sus significados. Para comprobar un estado exacto, guarda %ERRORLEVEL% inmediatamente y compara el valor almacenado, como se mostró antes.
Crear y probar un ejemplo de fallo y éxito
Este script crea un directorio nuevo para la demostración dentro del directorio temporal de Windows, con un nombre aleatorio. No elimina ninguna ruta. Si no puede crear el directorio o el archivo de entrada esperado ya existe, se detiene y devuelve el estado de configuración 2. Antes de ejecutar type, comprueba que el archivo de entrada no exista; solo muestra el mensaje de fallo esperado si el archivo sigue sin existir. Después crea el archivo de entrada, comprueba esa operación de escritura y lee el mismo archivo. El paquete proporcionado no incluye una ejecución de este ejemplo en el Símbolo del sistema de Windows. Las etiquetas visibles del código están en inglés y no se proporciona un bloque de salida.
Ejecuta este ejemplo:
@echo off
set "demo_dir=%TEMP%\batch-error-demo-%RANDOM%-%RANDOM%"
set "demo_file=%demo_dir%\input.txt"
if exist "%demo_dir%" (
echo Setup failed: the randomized demo directory is already present.
exit /b 2
)
mkdir "%demo_dir%" >nul 2>&1
if errorlevel 1 (
echo Setup failed: could not create the fresh demo directory.
exit /b 2
)
if exist "%demo_file%" (
echo Setup failed: the demo input is already present.
exit /b 2
)
type "%demo_file%" >nul 2>&1
set "command_status=%ERRORLEVEL%"
if not "%command_status%"=="0" (
if not exist "%demo_file%" (
echo Failure: input.txt was not found.
) else (
echo Failure: input.txt could not be read.
exit /b 1
)
) else (
echo Read input.txt successfully.
)
>"%demo_file%" echo ready
if errorlevel 1 (
echo Setup failed: could not create input.txt.
exit /b 2
)
type "%demo_file%" >nul 2>&1
if errorlevel 1 (
echo Failure: input.txt could not be read.
exit /b 1
)
echo Success: input.txt contains ready.
exit /b 0
La primera comprobación muestra el fallo esperado por la ausencia del archivo, y la lectura posterior muestra el caso de éxito. El script devuelve 0 tras leer el archivo correctamente, 1 si falla una lectura y 2 si la configuración no consigue crear un directorio nuevo para la demostración o el archivo de entrada. Deja el directorio con nombre único en %TEMP% para no eliminar datos ajenos; si quieres limpiarlo, revisa su contenido y elimina manualmente ese directorio concreto.
Registrar errores y devolver un estado útil
Un controlador de errores útil identifica la operación que falló, conserva la salida de diagnóstico cuando hace falta y devuelve al proceso que lo llamó un estado distinto de cero. Añade tanto la salida estándar como la salida de error estándar a un registro con >> "%LOGFILE%" 2>&1 y comprueba inmediatamente el estado del comando; la redirección captura la salida, pero por sí sola no gestiona el fallo.
Por ejemplo, después de establecer una ruta de registro adecuada, un script puede ejecutar un comando con >> "%LOGFILE%" 2>&1, guardar %ERRORLEVEL% en la línea siguiente y elegir una rama según ese valor. Si falla, imprime un mensaje que indique la operación y el archivo de registro, y luego usa exit /b 1; si tiene éxito, usa exit /b 0. Elige una ruta de registro en la que el usuario del script pueda escribir y no des por sentado que todos los códigos distintos de cero tienen la misma causa.