프로그램을 실행 중이며 반환 코드가 무엇인지보고 싶습니다 (다른 오류에 따라 다른 코드를 반환하기 때문에).
Bash에서 나는 이것을 실행하여 이것을 할 수 있다는 것을 안다.
에코 $?
Windows에서 cmd.exe를 사용할 때 어떻게해야합니까?
app.exe & echo %errorlevel%
프로그램을 실행 중이며 반환 코드가 무엇인지보고 싶습니다 (다른 오류에 따라 다른 코드를 반환하기 때문에).
Bash에서 나는 이것을 실행하여 이것을 할 수 있다는 것을 안다.
에코 $?
Windows에서 cmd.exe를 사용할 때 어떻게해야합니까?
app.exe & echo %errorlevel%
답변:
명명 된 의사 환경 변수 errorlevel
는 종료 코드를 저장합니다.
echo Exit Code is %errorlevel%
또한이 if
명령에는 특수 구문이 있습니다.
if errorlevel
자세한 내용 if /?
을 참조하십시오.
@echo off
my_nify_exe.exe
if errorlevel 1 (
echo Failure Reason Given is %errorlevel%
exit /b %errorlevel%
)
경고 : 환경 변수 이름을 설정하면 errorlevel
, %errorlevel%
그 값이 아닌 종료 코드를 반환합니다. ( set errorlevel=
)를 사용 하여 환경 변수를 지우면 환경 변수를 errorlevel
통한 실제 값에 액세스 할 수 있습니다 %errorlevel%
.
echo Exit Code is $LastExitCode
%ERRORLEVEL%
오류가 발생한 경우에도 0 인 사례를 발견 했습니다. %ERRORLEVEL%
cmd 파일을 체크인 할 때 발생했습니다 . 노력 start /wait
하지 않았다. 효과가 있었던 유일한 것은if errorlevel 1 (...)
string
되지 int
는 사용할 수 없습니다 의미 EQ
/ NEQ
효과.
콘솔 응용 프로그램에 ErrorLevel
대한 테스트 는 작동 하지만 dmihailescu 에서 암시 한 것처럼 명령 프롬프트에서 윈도우 응용 프로그램 (예 : Win32 기반) 을 실행하려고하면 작동하지 않습니다 . 윈도우 응용 프로그램은 백그라운드에서 실행되며 제어는 즉시 명령 프롬프트로 돌아갑니다 (대부분 0으로 프로세스가 성공적으로 생성 되었음을 나타냅니다 ). 윈도우 응용 프로그램이 결국 종료되면 종료 상태가 손실됩니다.ErrorLevel
그러나 다른 곳에서 언급 한 콘솔 기반 C ++ 실행기를 사용하는 대신 명령 프롬프트의 START /WAIT
명령을 사용하여 윈도우 응용 프로그램을 시작하는 것이 더 간단한 대안입니다 . 그러면 창 응용 프로그램이 시작되고 종료 될 때까지 기다린 다음에 설정된 프로세스의 종료 상태와 함께 명령 프롬프트로 제어가 반환됩니다 ErrorLevel
.
start /wait something.exe
echo %errorlevel%
오류 코드를 정확하게 일치 시키려면 (예 : 0) 다음을 사용하십시오.
@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
errorlevel
> = 0 과 일치 합니다 if /?
.를 참조하십시오 .
종료 코드가 있다고 생각하는 동안 해당 앱이 여전히 실행 중일 수 있으므로 콘솔에 연결되지 않은 프로그램을 사용할 때 올바르게 작동하지 않을 수 있습니다. C ++에서이를 수행하는 솔루션은 다음과 같습니다.
#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;
}
.BAT 및 .CMD 파일이 다르게 작동한다는 점은 주목할 가치가 있습니다.
https://ss64.com/nt/errorlevel.html 을 읽으면 다음 사항에 유의하십시오.
.CMD와 .BAT 배치 파일이 오류 수준을 설정하는 방식에는 중요한 차이점이 있습니다.
APPEND, ASSOC, PATH, PROMPT, FTYPE 및 SET '새로운'내부 명령을 실행하는 이전 .BAT 배치 스크립트는 오류가 발생하는 경우에만 ERRORLEVEL을 설정합니다. 따라서 배치 스크립트에 두 개의 명령이 있고 첫 번째 명령이 실패하면 ERRORLEVEL은 두 번째 명령이 성공한 후에도 설정된 상태로 유지됩니다.
이로 인해 문제 BAT 스크립트 디버깅이 더 어려워 질 수 있습니다. CMD 배치 스크립트는보다 일관되며 [source]를 실행하는 모든 명령 후에 ERRORLEVEL을 설정합니다.
이로 인해 연속 명령을 실행할 때 슬픔을 끝내지 못했지만 ERRORLEVEL은 실패한 경우에도 변경되지 않았습니다.
한 시점에서 Cygwin에서 Windows 이벤트 로그로 로그 이벤트를 정확하게 푸시해야했습니다. WEVL의 메시지가 사용자 정의되고 올바른 종료 코드, 세부 정보, 우선 순위, 메시지 등을 갖기를 원했습니다. 그래서 이것을 처리하기 위해 작은 Bash 스크립트를 만들었습니다. 여기 GitHub, logit.sh에 있습니다.
일부 발췌 :
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"
임시 파일 내용 부분은 다음과 같습니다.
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"
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
}
배치 스크립트를 실행하고 __create_event를 호출합니다.
cmd /c "$(cygpath -wa "$LGT_TEMP_FILE")"
__create_event