Pesquisou no "Win8 Como obter o prompt do CMD para mostrar o status da saída", como podemos fazer no Linux. Esta foi a melhor seleção e é precisa.
SDsolar 21/05
1
Você pode ver rapidamente o aplicativo retornado:app.exe & echo %errorlevel%
marbel82 19/02/19
Respostas:
976
Uma pseudo variável de ambiente chamada errorlevelarmazena o código de saída:
echo Exit Code is %errorlevel%
Além disso, o ifcomando possui uma sintaxe especial:
if errorlevel
Veja if /?para detalhes.
Exemplo
@echo off
my_nify_exe.exe
if errorlevel 1 (
echo Failure Reason Given is %errorlevel%
exit /b %errorlevel%
)
Aviso: Se você definir um nome de variável de ambiente errorlevel, %errorlevel%retornará esse valor e não o código de saída. Use ( set errorlevel=) para limpar a variável de ambiente, permitindo acesso ao valor real da errorlevelvia %errorlevel%variável de ambiente.
Se você estiver executando diretamente a partir de uma linha de comando do Windows e sempre vendo 0 voltou, ver a resposta de Gary: stackoverflow.com/a/11476681/31629
Ken
9
Além disso, se você estiver em PowerShell que você pode usarecho Exit Code is $LastExitCode
Brandon Pugh
11
Nota: "errorlevel 1" é verdadeiro se errorlevel> = 1. Portanto, "errorlevel 0" corresponderá a tudo. Veja se /?". Em vez disso, você pode usar "se% ERRORLEVEL% EQU 0 (..)".
Curtis Yallop 29/07
1
Casos encontrados em que %ERRORLEVEL%0 é o mesmo que ocorreu um erro. Aconteceu ao fazer o check- %ERRORLEVEL%in de um arquivo cmd. Tentar start /waitnão funcionou. A única coisa que funcionou éif errorlevel 1 (...)
AlikElzin-kilaka 13/04/2015
1
Conselho amigável:% ErrorLevel% é uma variável do shell, não uma variável de ambiente, e também retorna um stringnão int, o que significa que você não pode usar EQ/ NEQefetivamente.
precisa saber é o seguinte
277
O teste ErrorLevelfunciona para aplicativos de console , mas como sugerido pelo dmihailescu , isso não funcionará se você estiver tentando executar um aplicativo em janela (por exemplo, baseado em Win32) em um prompt de comando. Um aplicativo em janela será executado em segundo plano e o controle retornará imediatamente ao prompt de comando (provavelmente com ErrorLevelzero para indicar que o processo foi criado com êxito). Quando um aplicativo em janela eventualmente sai, seu status de saída é perdido.
Em vez de usar o iniciador de C ++ baseado em console mencionado em outro lugar, uma alternativa mais simples é iniciar um aplicativo em janela usando o comando do prompt de START /WAITcomando. Isso iniciará o aplicativo em janela, espere que ele saia e retorne o controle ao prompt de comando com o status de saída do processo definido ErrorLevel.
Muito obrigado pela ideia "START / wait". Isso funcionou para mim:) #
214 Timotei
3
boa pegada. Eu não sabia sobre esse comando. Acabei de vê-lo trabalhando para> start / wait notepad.exe
dmihailescu
1
Outra razão pela qual ele pode não funcionar (sempre zero) é quando está dentro de um ifou for. Considere usar !errorlevel!, como descrito nesta resposta .
Não. Vars, comandos (incluindo "if") e "equ" funcionam, não importa qual seja o caso.
Curtis Yallop
14
Pode não funcionar corretamente ao usar um programa que não está conectado ao console, porque esse aplicativo ainda pode estar em execução enquanto você acha que possui o código de saída. Uma solução para fazê-lo em C ++ é apresentada abaixo:
#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 FALSE0,// 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());returnGetLastError();}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;}
Há uma diferença importante entre a maneira como os arquivos em lotes .CMD e .BAT definem os níveis de erro:
Um script em lote .BAT antigo executando os 'novos' comandos internos: APPEND, ASSOC, PATH, PROMPT, FTYPE e SET somente definirão ERRORLEVEL se ocorrer um erro. Portanto, se você tiver dois comandos no script em lote e o primeiro falhar, o ERRORLEVEL permanecerá definido mesmo depois que o segundo comando for bem-sucedido.
Isso pode dificultar a depuração de um script BAT com problema, um script em lote CMD é mais consistente e definirá ERRORLEVEL após cada comando que você executa [origem].
Isso estava me causando dor de cabeça, enquanto eu executava comandos sucessivos, mas o ERRORLEVEL permaneceria inalterado mesmo no caso de uma falha.
Em um ponto, eu precisava enviar com precisão os eventos de log do Cygwin para o log de eventos do Windows. Eu queria que as mensagens no WEVL fossem personalizadas, tivessem o código de saída correto, detalhes, prioridades, mensagem, etc. Então, criei um pequeno script Bash para cuidar disso. Aqui está no GitHub, logit.sh .
Alguns trechos:
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"
Aqui está a parte do conteúdo do arquivo temporário:
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"
Aqui está uma função para criar eventos no 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
}
Executando o script em lote e chamando __create_event:
app.exe & echo %errorlevel%
Respostas:
Uma pseudo variável de ambiente chamada
errorlevel
armazena o código de saída:Além disso, o
if
comando possui uma sintaxe especial:Veja
if /?
para detalhes.Exemplo
Aviso: Se você definir um nome de variável de ambiente
errorlevel
,%errorlevel%
retornará esse valor e não o código de saída. Use (set errorlevel=
) para limpar a variável de ambiente, permitindo acesso ao valor real daerrorlevel
via%errorlevel%
variável de ambiente.fonte
echo Exit Code is $LastExitCode
%ERRORLEVEL%
0 é o mesmo que ocorreu um erro. Aconteceu ao fazer o check-%ERRORLEVEL%
in de um arquivo cmd. Tentarstart /wait
não funcionou. A única coisa que funcionou éif errorlevel 1 (...)
string
nãoint
, o que significa que você não pode usarEQ
/NEQ
efetivamente.O teste
ErrorLevel
funciona para aplicativos de console , mas como sugerido pelo dmihailescu , isso não funcionará se você estiver tentando executar um aplicativo em janela (por exemplo, baseado em Win32) em um prompt de comando. Um aplicativo em janela será executado em segundo plano e o controle retornará imediatamente ao prompt de comando (provavelmente comErrorLevel
zero para indicar que o processo foi criado com êxito). Quando um aplicativo em janela eventualmente sai, seu status de saída é perdido.Em vez de usar o iniciador de C ++ baseado em console mencionado em outro lugar, uma alternativa mais simples é iniciar um aplicativo em janela usando o comando do prompt de
START /WAIT
comando. Isso iniciará o aplicativo em janela, espere que ele saia e retorne o controle ao prompt de comando com o status de saída do processo definidoErrorLevel
.fonte
if
oufor
. Considere usar!errorlevel!
, como descrito nesta resposta .Use a variável ERRORLEVEL interna:
Mas cuidado se um aplicativo definiu uma variável de ambiente chamada ERRORLEVEL !
fonte
$LastExitCode
no PowerShell.Se você deseja corresponder exatamente ao código de erro (por exemplo, igual a 0), use o seguinte:
if errorlevel 0
corresponde aerrorlevel
> = 0. Vejaif /?
.fonte
Pode não funcionar corretamente ao usar um programa que não está conectado ao console, porque esse aplicativo ainda pode estar em execução enquanto você acha que possui o código de saída. Uma solução para fazê-lo em C ++ é apresentada abaixo:
fonte
Vale a pena notar que os arquivos .BAT e .CMD funcionam de maneira diferente.
Lendo https://ss64.com/nt/errorlevel.html , observa o seguinte:
Isso estava me causando dor de cabeça, enquanto eu executava comandos sucessivos, mas o ERRORLEVEL permaneceria inalterado mesmo no caso de uma falha.
fonte
Em um ponto, eu precisava enviar com precisão os eventos de log do Cygwin para o log de eventos do Windows. Eu queria que as mensagens no WEVL fossem personalizadas, tivessem o código de saída correto, detalhes, prioridades, mensagem, etc. Então, criei um pequeno script Bash para cuidar disso. Aqui está no GitHub, logit.sh .
Alguns trechos:
Aqui está a parte do conteúdo do arquivo temporário:
Aqui está uma função para criar eventos no WEVL:
Executando o script em lote e chamando __create_event:
fonte