¿Cómo obtengo el código de salida de la aplicación desde una línea de comandos de Windows?

Estoy ejecutando un programa y quiero ver cuál es su código de retorno (ya que devuelve diferentes códigos basados ​​en diferentes errores).

Sé que en Bash puedo hacer esto corriendo

echo $?

¿Qué hago cuando uso cmd.exe en Windows?

preguntado el 02 de diciembre de 08 a las 16:12

Busqué en Google "Win8 Cómo hacer que el indicador de CMD muestre el estado de salida" como podemos hacer en Linux. Esta fue la mejor selección y es precisa. -

Puede ver rápidamente qué aplicación devuelve: app.exe & echo %errorlevel% -

7 Respuestas

Una pseudo variable de entorno denominada errorlevel almacena el código de salida:

echo Exit Code is %errorlevel%

También el if El comando tiene una sintaxis especial:

if errorlevel

Vea if /? para más detalles.

Ejemplo

@echo off
my_nify_exe.exe
if errorlevel 1 (
   echo Failure Reason Given is %errorlevel%
   exit /b %errorlevel%
)

Advertencia: si establece un nombre de variable de entorno errorlevel, %errorlevel% devolverá ese valor y no el código de salida. Usar (set errorlevel=) para borrar la variable de entorno, permitiendo el acceso al valor real de errorlevel mediante el %errorlevel% Variable ambiental.

Respondido el 18 de diciembre de 18 a las 16:12

Si está ejecutando directamente desde una línea de comandos de Windows y siempre ve 0 devuelto, consulte la respuesta de Gary: stackoverflow.com/a/11476681/31629 - Conocido

Además, si está en PowerShell, puede usar echo Exit Code is $LastExitCode - brandon pug

Nota: "errorlevel 1" es verdadero si errorlevel> = 1. Por lo tanto, "errorlevel 0" coincidirá con todo. Ve si /?". En su lugar, puede utilizar "if% ERRORLEVEL% EQU 0 (..)". - Curtis Yallop

Casos encontrados donde %ERRORLEVEL% es 0 aunque se haya producido un error. Sucedió al comprobar %ERRORLEVEL% en un archivo cmd. Difícil start /wait no funcionó. Lo único que funcionó es if errorlevel 1 (...) - AlikElzin-kilaka

Consejo amistoso:% ErrorLevel% es una variable de shell, no una variable de entorno, y también devuelve un string no un int, lo que significa que no puedes usar EQ/NEQ efectivamente. - kayleefrye_ondeck

Pruebas ErrorLevel trabaja para consolar aplicaciones, pero como se insinuó por dmihailescu, esto no funcionará si está intentando ejecutar un ventana aplicación (por ejemplo, basada en Win32) desde un símbolo del sistema. Una aplicación con ventana se ejecutará en segundo plano y el control volverá inmediatamente al símbolo del sistema (probablemente con un ErrorLevel de cero para indicar que el proceso fue creado exitosamente). Cuando una aplicación con ventana finalmente sale, su estado de salida se pierde.

Sin embargo, en lugar de usar el lanzador de C ++ basado en consola mencionado en otra parte, una alternativa más simple es iniciar una aplicación con ventana usando el símbolo del sistema START /WAIT mando. Esto iniciará la aplicación en ventana, esperará a que salga y luego devolverá el control al símbolo del sistema con el estado de salida del proceso configurado en ErrorLevel.

start /wait something.exe
echo %errorlevel%

Respondido el 19 de junio de 18 a las 19:06

Muchas gracias por la idea de "EMPEZAR / esperar". Eso funcionó para mí :) - Timoteo

buena atrapada. No sabía nada de ese comando. Lo acabo de ver funcionar para> iniciar / esperar notepad.exe - dmihailescu

Otra razón por la que podría no funcionar (siempre cero) es cuando está dentro de un if or for. Considere usar !errorlevel! en cambio, como descrito en esta respuesta. - romano starkov

Utilice la variable ERRORLEVEL incorporada:

echo %ERRORLEVEL%

Pero tenga cuidado si una aplicación ha definido una variable de entorno llamada ERRORLEVEL!

Respondido el 30 de junio de 19 a las 21:06

No es una variable de entorno real (que es, obviamente, la razón por la que deja de funcionar si hay is una variable nombrada de esa manera). - Joey

@SteelBrain: Se llama $LastExitCode en PowerShell. - Alex A.

Si desea hacer coincidir el código de error exactamente (por ejemplo, igual a 0), use esto:

@echo off
my_nify_exe.exe
if %ERRORLEVEL% EQU 0 (
   echo Success
) else (
   echo Failure Reason Given is %errorlevel%
   exit /b %errorlevel%
)

if errorlevel 0 cerillas errorlevel > = 0. Ver if /?.

Respondido el 20 de junio de 18 a las 03:06

¿Es sensible a mayúsculas y minúsculas? - Nishant

No. vars, comandos (incluyendo "if") y "equ" funcionan sin importar cuál sea el caso. - Curtis Yallop

Es posible que no funcione correctamente cuando se usa un programa que no está adjunto a la consola, porque esa aplicación podría seguir ejecutándose mientras cree que tiene el código de salida. Una solución para hacerlo en C ++ se ve a continuación:

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "tchar.h"
#include "stdio.h"
#include "shellapi.h"

int _tmain( int argc, TCHAR *argv[] )
{

    CString cmdline(GetCommandLineW());
    cmdline.TrimLeft('\"');
    CString self(argv[0]);
    self.Trim('\"');
    CString args = cmdline.Mid(self.GetLength()+1);
    args.TrimLeft(_T("\" "));
    printf("Arguments passed: '%ws'\n",args);
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    if( argc < 2 )
    {
        printf("Usage: %s arg1,arg2....\n", argv[0]);
        return -1;
    }

    CString strCmd(args);
    // Start the child process. 
    if( !CreateProcess( NULL,   // No module name (use command line)
        (LPTSTR)(strCmd.GetString()),        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    {
        printf( "CreateProcess failed (%d)\n", GetLastError() );
        return GetLastError();
    }
    else
        printf( "Waiting for \"%ws\" to exit.....\n", strCmd );

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );
    int result = -1;
    if(!GetExitCodeProcess(pi.hProcess,(LPDWORD)&result))
    { 
        printf("GetExitCodeProcess() failed (%d)\n", GetLastError() );
    }
    else
        printf("The exit code for '%ws' is %d\n",(LPTSTR)(strCmd.GetString()), result );
    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
    return result;
}

Respondido 16 ago 11, 13:08

En algunas configuraciones debe agregar #include para que se reconozca el tipo de CString. - jake opj

Vale la pena señalar que los archivos .BAT y .CMD funcionan de manera diferente.

La lectura https://ss64.com/nt/errorlevel.html señala lo siguiente:

Existe una diferencia clave entre la forma en que los archivos por lotes .CMD y .BAT establecen niveles de error:

Un antiguo script por lotes .BAT que ejecuta los 'nuevos' comandos internos: APPEND, ASSOC, PATH, PROMPT, FTYPE y SET solo establecerá ERRORLEVEL si se produce un error. Entonces, si tiene dos comandos en el script por lotes y el primero falla, ERRORLEVEL permanecerá configurado incluso después de que el segundo comando tenga éxito.

Esto puede dificultar la depuración de un script BAT problemático, un script por lotes CMD es más consistente y establecerá ERRORLEVEL después de cada comando que ejecute [fuente].

Esto me estaba causando un sinfín de dolor mientras ejecutaba comandos sucesivos, pero ERRORLEVEL permanecería sin cambios incluso en el caso de una falla.

Respondido el 18 de Septiembre de 18 a las 07:09

En un momento, necesitaba enviar con precisión los eventos de registro de Cygwin al registro de eventos de Windows. Quería que los mensajes en WEVL fueran personalizados, tuvieran el código de salida correcto, los detalles, las prioridades, el mensaje, etc. Así que creé un pequeño script Bash para encargarme de esto. Aquí está en GitHub, logit.sh.

Algunos extractos:

usage: logit.sh [-h] [-p] [-i=n] [-s] <description>
example: logit.sh -p error -i 501 -s myscript.sh "failed to run the mount command"

Aquí está la parte del contenido del archivo temporal:

LGT_TEMP_FILE="$(mktemp --suffix .cmd)"
cat<<EOF>$LGT_TEMP_FILE
    @echo off
    set LGT_EXITCODE="$LGT_ID"
    exit /b %LGT_ID%
EOF
unix2dos "$LGT_TEMP_FILE"

Aquí hay una función para crear eventos en WEVL:

__create_event () {
    local cmd="eventcreate /ID $LGT_ID /L Application /SO $LGT_SOURCE /T $LGT_PRIORITY /D "
    if [[ "$1" == *';'* ]]; then
        local IFS=';'
        for i in "$1"; do
            $cmd "$i" &>/dev/null
        done
    else
        $cmd "$LGT_DESC" &>/dev/null
    fi
}

Ejecutando el script por lotes y llamando a __create_event:

cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"
__create_event

Respondido 21 Abr '17, 16:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.