functions code batch bat windows batch-file cmd exit errorlevel

windows - code - Saliendo del lote con `EXIT/BX` donde X>=1 actúa como si el comando se completara con éxito cuando se usa && o || operadores entre llamadas por lotes



windows batch functions (4)

Estoy tratando de encadenar una serie de archivos .bat usando el comando EXIT /BX para devolver el éxito o el fracaso y && y || para la ejecución condicional del siguiente .bat (por ejemplo, a.bat && b.bat ).

Independientemente de si llamo EXIT /B 0 o cualquier otra cosa para finalizar a.bat, a.bat && b.bat llamará a b.bat después. Tengo entendido que EXIT /B 0 debería establecer ERRORLEVEL=0 , que es éxito, por lo que && debería continuar. El contrapunto a esto es que llamar a EXIT /B 1 debe establecer ERRORLEVEL=1 que es un error, por lo que && debería detenerse. ¿Que me estoy perdiendo aqui?

Ejemplo trivializado:

Para comandos no por lotes, actuando como se espera:

C:/> echo test|findstr test>NUL && echo yes yes C:/> echo test|findstr test>NUL || echo yes C:/> echo test|findstr nope>NUL && echo yes C:/> echo test|findstr nope>NUL || echo yes yes

Usar EXIT /B siempre ve a.bat como exitoso:

C:/> echo @EXIT /B 0 > a.bat C:/> a.bat && echo yes yes C:/> a.bat || echo yes C:/> echo @EXIT /B 1 > a.bat C:/> a.bat && echo yes yes C:/> a.bat || echo yes

¿Cómo puedo salir de a.bat para que a.bat && b.bat y a.bat || b.bat a.bat || b.bat comportan como se espera?

Todos los comandos se ejecutan en cmd.exe en Windows XP SP3.


Creo que está obteniendo Errorlevel=0 porque está ejecutando a.bat (independientemente del código de retorno).

Usted fallaría la comprobación si a.bat no existiera. CALL es la única forma que conozco para extraer el entorno de a.bat .


Funciona como debería cuando se usa la llamada para ejecutar scripts por lotes que contienen una declaración de salida:

C:/>echo @EXIT /B 1 > a.bat C:/>call a.bat && echo yes C:/>call a.bat || echo yes yes

Por cierto, dice erróneamente en los documentos de Microsoft :

La llamada no tiene efecto en el símbolo del sistema cuando se usa fuera de un script o archivo de proceso por lotes.


Si me preguntas, los códigos de salida en los archivos por lotes se rompen por la misma razón, pero hay una solución pirata que puedes usar. Como la última línea de su archivo por lotes, use:

@%COMSPEC% /C exit 1 >nul

Dado que este es un proceso real que se inicia, se obtiene un código de salida de proceso real y && y || trabajará.


Si usa start /wait , también puede usar esto en una aplicación de Windows muy simple (escrita en C #) llamada por los archivos de proceso por lotes de DOS de la siguiente manera:

static class Program { [STAThread] static void Main(string[] args) { Environment.ExitCode = Convert.ToInt32(args[0]); } }

Luego, la aplicación puede ser llamada por su archivo por lotes de DOS y evaluar el resultado. es decir

c:> start /wait SetRC 1 c:> if "%errorlevel%"=="1" goto abort

NOTA: la /wait no es necesaria en un archivo por lotes.

Puede pasar el código de retorno que desee como un argumento a su program.cs y obtenerlo de esta manera garantizada.