5

I am using Python subprocess to run external scripts on Windows 7. I am trying to get the exit code.


In case 1, I run a python script test1.py.

test1.py

import sys
sys.exit(24)   <--exit code

myscript1.py

import subprocess
process = subprocess.Popen(["python", "C:\\path\\to\\test1.py"], stdout=subprocess.PIPE)
process.wait()
print process.returncode

In Windows command prompt, when I run the script, I get the following output:

>python test1.py
>
>echo %errorlevel%
>24
>
>python myscript1.py
>24

So, you can see that subprocess is able to get the correct exit code in this case.


In case 2, I run a batch file test2.cmd.

test2.cmd

EXIT /B 56   <--exit code

myscript2.py

import subprocess
process = subprocess.Popen(["C:\\path\\to\\test2.cmd"], stdout=subprocess.PIPE)
process.wait()
print process.returncode

In Windows command prompt, when I run the script, I get the following output:

>test2.cmd
>
>echo %errorlevel%
>56
>
>python myscript2.py
>56

So, you can see that subprocess is also able to get the correct exit code in this case.


In case 3, I run a SikuliX script.

test3.sikuli

xxx xxx (sikuli script here)
xxx xxx
...
exit(16)   <--exit code

myscript3.py

import subprocess
process = subprocess.Popen(["C:\\path\\to\\runsikuli.cmd", "-r", "C:\\path\\to\\sikuli-script.sikuli"], stdout=subprocess.PIPE)
process.wait()
print process.returncode

In Windows command prompt, when I run the script, I get the following output:

>C:\path\to\runsikuli.cmd -r C:\path\to\sikuli-script.sikuli
>... (stdout + stderr)
>16
>
>echo %errorlevel%
>16
>
>python myscript3.py
>0

In case 3, when I run the script manually in the command prompt, it is able to set the %errorlevel%. When I run the script using Python subprocess, subprocess is unable to get the correct exit code. It always return 0.

Why Python subprocess failed to get the exit code in case 3?

11
  • why do you run jython script using <sikulicmd> <arg1> <arg2>? What is the exact command that you run manually that ends with echo %errorlevel%? Do you need the output (stdout/stderr) from the jython script? Unrelated: why do you need both python and jython? Could jython along be enough? Commented Jul 3, 2014 at 20:16
  • @J.F.Sebastian Hi Sebastian, I have added more description of the problems. Commented Jul 4, 2014 at 13:45
  • what happens if add a long pause in the jython script? Does the parent python script wait for it? Try: print(subprocess.call(r'C:\path\to\runsikuli.cmd -r C:\path\to\sikuli-script.sikuli & echo %errorlevel%', shell=True)) Commented Jul 4, 2014 at 14:00
  • @J.F.Sebastian Hi Sebastian, I have added a long pause in the Jython script using time.sleep(30). The parent python script waits for it to complete. When I run this command print(subprocess.call(r'C:\path\to\runsikuli.cmd -r C:\path\to\sikuli-script.sikuli & echo %errorlevel%', shell=True)), it prints out all the output from the Jython script execution. In the end, it prints out 2 exit code, 1 returned by echo %errorlevel%, 1 returned by print(..), both are 0. The problem is, when I run the same Jython script manually in command prompt, the %errorlevel% is correctly set. Commented Jul 7, 2014 at 1:37
  • what happens if you run the exact command that is inside r'' quotes literally (just copy-paste it) in the command prompt (is it cmd.exe or PowerShell?)? Commented Jul 8, 2014 at 1:07

2 Answers 2

3

As your comment says if you run the same command then both the command prompt and using Python subprocess module produce the same result (0 exit code).

You may see different exit codes because you use different commands. No surprise here. Python subprocess module returns correct (for a given command) exit code.


If it doesn't return the right exit status then you could add & exit at the end of your cmd.exe command as a workaround to get the correct return code, see "subprocess on Windows: wrong return code with shell=True" on Python issue tracker:

from subprocess import check_call

check_call(r'C:\path\to\runsikuli.cmd -r C:\path\to\sikuli-script.sikuli & exit',
           shell=True)
Sign up to request clarification or add additional context in comments.

6 Comments

Hi Sebastian, the command gives exit code 0 because you have added & echo %errorlevel% at the end of the command you gave me in r''. When I run my original command (without & echo ..) in cmd.exe, and then I manually run echo %errorlevel% in cmd.exe, it shows the exit code correctly (not 0). When I copy-paste my original command (without & echo ..) into Python subprocess and run it, it shows that exit code is 0.
@PatrickL: no, you said: "both are zero." echo %errrolevel% prints exit code of the previous command, not the echo command itself. And yes, adding & echo .. makes subprocess.call() to return 0. It doesn't make the first command to return 0.
To avoid confusion, let me describe the commands i used in details. When I run C:\path\to\runsikuli.cmd -r C:\path\to\sikuli-script.sikuli in cmd.exe, and then run echo %errrolevel% in cmd.exe, it shows 16. When I run your command C:\path\to\runsikuli.cmd -r C:\path\to\sikuli-script.sikuli & echo %errorlevel% in cmd.exe, it shows 0. When I run r'C:\path\to\runsikuli.cmd -r C:\path\to\sikuli-script.sikuli' in Python subprocess and print the return code, it shows 0.
@PatrickL: what happens if you run a command e.g. python -c "exit(11)" before running ...runsikuli.cmd ...sikuli & echo %errorlevel% Does it print 11 or 0 in the end? What happens if you run python -c "exit(12)", and then run echo %errorlevel% in cmd.exe? What happens if you run python -c "exit(13)" & echo %errorlevel%? Does it show 13? What happens if you run cmd /c "python -c "exit(14)"", and then run echo %errorlevel% in cmd.exe? (you might need to add ^ before internal quotes ").
When I run python -c "exit(11)" before running ...runsikuli.cmd ...sikuli & echo %errorlevel%, it prints 11. When I run python -c "exit(12)" and then run echo %errorlevel%, it prints 12. When I run python -c "exit(13)" & echo %errorlevel%, it prints 12. When I run cmd /c "python -c "exit(14)"" with ^ before internal quotes, it prints 14. When I run cmd /c "python -c "exit(14)"" without ^ before internal quotes, it prints 14. Please note that all these commands are run in sequence in the same cmd.exe window.
|
0

Although this does not answer the question directly, you can use this method to get the exit code indirectly in Python subprocess.

Create a batch file batch.cmd. In the file, call the command that you want to execute like this:

call %1 -r %2
EXIT /B %errorlevel%

In your python script:

import subprocess
exitcode = subprocess.call(r'C:\path\to\batch.cmd C:\path\to\runsikuli.cmd C:\path\to\sikuli-script.sikuli', shell=True)
print "Exit Code = "+str(exitcode)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.