简体   繁体   中英

How to get the exit code from a bash script invoked with winApi CreateProcess?

I'm using CreateProcess to invoke a bash script via Cygwin's bash.exe. The script runs fine, and I'm even able to redirect stdout and stderr to display within my own window. The only problem is that I can't seem to get the bash script's exit code.

Here's how I'm launching the script:

PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof(pi) );

STARTUPINFO si; 
si.cb = sizeof (STARTUPINFO); 
si.lpReserved = NULL; 
si.lpDesktop = NULL;
si.lpTitle = NULL; 
si.dwX = 0; 
si.dwY = 0; 
si.dwXSize = 0; 
si.dwYSize = 0; 
si.dwXCountChars = 0; 
si.dwYCountChars = 0; 
si.dwFillAttribute = 0; 
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 
si.wShowWindow = SW_HIDE; 
si.cbReserved2 = 0; 
si.lpReserved2 = NULL; 
si.hStdOutput = hChildStdOut;
si.hStdInput  = NULL;
si.hStdError  = hChildStdErr;

CreateProcessW( NULL, 
    L"bash.exe script.sh file_to_process", 
    NULL, 
    NULL, 
    TRUE, 
    CREATE_NEW_CONSOLE, 
    NULL, 
    NULL, 
    &si, 
    &pi);

hChildProcess = pi.hProcess;

And here is how I'm attempting to get the exit code:

WaitForSingleObject(hChildProcess, 0);
DWORD exitCode = 999;
GetExitCodeProcess(hChildProcess, &exitCode);
DWORD lastError = GetLastError();

Both exitCode and lastError seem to always be zero regardless of the exit code that should have been returned by the script.

Update

As cwgem pointed out, the script was using exit to exit the script. I tried changing them all to return , which exitCode = 1, which is not a value returned by the script. A bit of Googling got me $(exit n) , which sort of works, but I only get the final exit code from the script (currently 7 for testing, but would normally be 0).

So, for example, I have the following block in my script:

if [ `/cygdrive/c/cygwin/bin/find $root -name '*.xml' | grep -c .xml` -eq 0 ] ; then
echo No XMLs present in $root!
$(exit 2)
fi

When I test this path I get the "No XMLs" message in stdout, as expected, but I don't get 2 as my exit code. Instead I get 7, which as I noted above is the final exit statement in the script.

I can create a variable to store my exitcode and return that at the end, but that doesn't feel like the correct solution since I'd potentially be executing code that I shouldn't.

I should perhaps note that I'm neither the author nor the maintainer of the script, I've just been asked to run it from my application.

You should check your script's execution flow, as bash will return as the exit code the return value of the last run command unless you:

  • Exit forcefully using exit [returncode]
  • set -e at the beginning of the script, which will exit immediately when any command exits with a non-zero value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM