¿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 ejecutando

Echo??

Qué hago cuando uso cmd.exe en Windows?

Author: Skrud, 2008-12-02

7 answers

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

echo Exit Code is %errorlevel%

Además, el comando if tiene una sintaxis especial:

if errorlevel

Véase 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 entornoerrorlevel, %errorlevel% devolverá ese valor y no el código de salida. Use (set errorlevel=) para borrar la variable de entorno, permitiendo el acceso al valor verdadero de errorlevel a través de la variable de entorno %errorlevel%.

 795
Author: Samuel Renkert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-09 16:11:59

Testing ErrorLevelfunciona para consoleaplicaciones, pero como se insinúa en por dmihailescu, esto no funcionará si está tratando de ejecutar una aplicación windowed (por ejemplo, basada en Win32) desde un símbolo del sistema. Una aplicación de ventana se ejecutará en segundo plano, y control volverá inmediatamente al símbolo del sistema (muy probablemente con un ErrorLevel de cero para indicar que el proceso fue creado con éxito). Cuando una aplicación de ventana finalmente sale, su estado de salida es perder.

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

start /wait something.exe
echo %errorlevel%
 203
Author: Gary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-19 18:06:54

Utilice la variable ERRORLEVEL incorporada:

echo %ERRORLEVEL%

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

 87
Author: Adam Rosenfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-16 12:44:10

Podría no funcionar correctamente cuando se utiliza un programa que no está conectado a la consola, porque esa aplicación podría seguir ejecutándose mientras crees que tienes 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;
}
 12
Author: dmihailescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-16 12:44:41

Si desea que el código de error coincida exactamente (eg es 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 coincidencias errorlevel > = 0. Véase if /?.

 10
Author: Curtis Yallop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-20 02:02:45

En un momento tuve que empujar 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, detalles, prioridades, mensaje, etc. Así que creé un pequeño guión de 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_ _ crear _ evento:

cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"
__create_event
 0
Author: jonretting,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-21 15:43:56

Vale la pena señalar que .BATE y .Los archivos CMD funcionan de manera diferente.

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

Hay una diferencia clave entre el camino .CMD y .BAT batch files set errorlevels:

Un viejo .El script BAT batch que ejecuta los comandos internos' new': APPEND, ASSOC, PATH, PROMPT, FTYPE y SET solo establecerá ERRORLEVEL si se produce un error. Así que si tiene dos comandos en el script por lotes y el primero falla, el NIVEL de ERROR permanecerá establecido incluso después de que el segundo comando tenga éxito.

Esto puede hacer que la depuración de un script BAT problema sea más difícil, un script por lotes CMD es más consistente y establecerá ERRORLEVEL después de cada comando que ejecute [source].

Esto me estaba causando un dolor interminable ya que estaba ejecutando comandos sucesivos, pero el NIVEL de error permanecería sin cambios incluso en el caso de un fallo.

 0
Author: RockDoctor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-18 06:13:09