subprocess returncode windows

A

Andrew

Hello,

I'm running into a strange situation with getting incorrect
returncodes / exit status from python subprocess.call. I'm using a
python script (runtime 2.6.1 on windows) to automate the deploy of
java applications to glassfish application server. Below is an example
of using a subprocess call to test the success / failure of the
glassfish CLI tool "asadmin"

Example.py:
----------------------
import sys
from subprocess import *

try:
retcode = call("c:/glassfish/bin/asadmin.bat " + "list-system-
properties --host mydomain --port 4848 --user admin server-01",
shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e
----------------------

However, when I execute it, it gets the same returncode whether it
fails or succeeds (0).

---------------------
C:\>python z:\bin\example.py
Please enter the admin password> ***Enters Good Password***
IIOP_SSL_MUTUALAUTH_PORT=33920
JMX_SYSTEM_CONNECTOR_PORT=38686
IIOP_LISTENER_PORT=33700
IIOP_SSL_LISTENER_PORT=33820
HTTP_LISTENER_PORT=38080
AJP_INSTANCE_NAME=WebReporting-01
HTTP_SSL_LISTENER_PORT=38181
JMS_PROVIDER_PORT=37676
AJP_PORT=18009
Command list-system-properties executed successfully.
Child returned 0

C:\>python z:\bin\example.py
Please enter the admin password>***Enters BAD PASSWORD***
Invalid user or password
CLI137 Command list-system-properties failed.
Child returned 0

C:\>
------------------------------------------------

When I execute this manually from the cmd.exe and I check the
%errorlevel% it returns the correct levels:

-----------------------------------------------
C:\>c:\glassfish\bin\asadmin.bat list-system-properties --host
mydomain --port 4848 --user admin server-01
Please enter the admin password>***GOOD PASSWORD***
IIOP_SSL_MUTUALAUTH_PORT=33920
JMX_SYSTEM_CONNECTOR_PORT=38686
IIOP_LISTENER_PORT=33700
IIOP_SSL_LISTENER_PORT=33820
HTTP_LISTENER_PORT=38080
AJP_INSTANCE_NAME=WebReporting-01
HTTP_SSL_LISTENER_PORT=38181
JMS_PROVIDER_PORT=37676
AJP_PORT=18009
Command list-system-properties executed successfully.

C:\>echo %errorlevel%
0

C:\>c:\glassfish\bin\asadmin.bat list-system-properties --host
mydomain --port 4848 --user admin server-01
Please enter the admin password>***BAD PASSWORD***
Invalid user or password
CLI137 Command list-system-properties failed.

C:\>echo %errorlevel%
1

C:\>
-------------------------------------

I'm guessing that returncode isn't the same thing as exit status? Is
there a way to get exit status using a subprocess function instead of
returncode? Is this the right way to go about this?

Thanks for any direction / advice you can provide.

Andrew
 
A

Andrew

Andrew schrieb:


I'm running into a strange situation with getting incorrect
returncodes / exit status from python subprocess.call. I'm using a
python script (runtime 2.6.1 on windows) to automate the deploy of
java applications to glassfish application server. Below is an example
of using a subprocess call to test the success / failure of the
glassfish CLI tool "asadmin"
Example.py:
try:
    retcode = call("c:/glassfish/bin/asadmin.bat " + "list-system-
properties --host mydomain --port 4848 --user admin server-01",
shell=True)
    if retcode < 0:
        print >>sys.stderr, "Child was terminated by signal", -retcode
    else:
        print >>sys.stderr, "Child returned", retcode
except OSError, e:
    print >>sys.stderr, "Execution failed:", e

Don't use shell=True! Instead use a list of arguments without shell=True:

call(["c:/glassfish/bin/asadmin.bat", "list-system-properties", "--host
mydomain", "--port 4848", "--user admin", "server-01"])

That should solve your quoting issues on Windows and fix your code.
shell=True is considered evil and should be avoided whenever possible.

Christian

Thanks Christian,

I've removed shell=True, unfortunately, if I structure the call like:

call(["c:/glassfish/bin/asadmin.bat", "list-system-properties", "--
host
mydomain", "--port 4848", "--user admin", "server-01"])

It doesn't seem to recognize any arguments after list-system-
properties. If I structure it like:

call("c:/glassfish/bin/asadmin.bat "+"list-system-properties --host
mydomain --port 4848 --user admin server-01")

Then it executes correctly but still gives invalid returncode of 0
when it fails instead of 1.

Andrew
 
A

Andrew

En Tue, 16 Dec 2008 17:21:35 -0200, Andrew <[email protected]>  
escribió:


I've removed shell=True, unfortunately, if I structure the call like:
call(["c:/glassfish/bin/asadmin.bat", "list-system-properties", "--
host
mydomain", "--port 4848", "--user admin", "server-01"])
It doesn't seem to recognize any arguments after list-system-
properties.

Should be:

call(["c:/glassfish/bin/asadmin.bat", "list-system-properties", "--host",
"mydomain", "--port", "4848", "--user", "admin", "server-01"])

*Every* argument should be an item in the list (your way, "--port 4848"  
becomes a single argument, not two: option plus value)
(This is independent of your other issue)
If I structure it like:
call("c:/glassfish/bin/asadmin.bat "+"list-system-properties --host
mydomain --port 4848 --user admin server-01")
Then it executes correctly but still gives invalid returncode of 0
when it fails instead of 1.

A similar example works fine for me:

C:\temp>type ret.c
#include <stdlib.h>

int main(int argc, char* argv[])
{
   return atoi(argv[1]);

}

C:\temp>ret 5

C:\temp>echo %errorlevel%
5

C:\temp>type testret.bat
ret %1

C:\temp>testret 3

C:\temp>ret 3

C:\temp>echo %errorlevel%
3

C:\temp>type testret.py
 from subprocess import call
ret = call(["testret.bat", "42"])
print "testret.bat exit code =", ret

C:\temp>python testret.py

C:\temp>ret 42
testret.bat exit code = 42

C:\temp>python -V
Python 2.6

C:\temp>ver

Microsoft Windows XP [Versión 5.1.2600]

I've tried this several ways now. It seems to be something specific
with python and asadmin.bat.

I've tried the following manually in the cmd.exe prompt:

------
C:\temp>c:\glassfish\bin\asadmin.bat list-system-properties
Instance-01
.....
properties here
.....

Command list-system-properties executed successfully.

C:\temp>echo %errorlevel%
0

C:\temp>c:\glassfish\bin\asadmin.bat list-system-properties
Instance-05 //note that Instance-05 does not exist
Cannot determine type for target : Instance-05
CLI137 Command list-system-properties failed.

C:\temp>echo %errorlevel%
1

C:\temp>ping 019293.com
Ping request could not find host 019293.com. Please check the name and
try again
..

C:\temp>echo %errorlevel%
1

C:\temp>ping google.com

Pinging google.com [74.125.45.100] with 32 bytes of data:

Reply from 74.125.45.100: bytes=32 time=48ms TTL=234
Reply from 74.125.45.100: bytes=32 time=66ms TTL=234
Reply from 74.125.45.100: bytes=32 time=63ms TTL=234
Reply from 74.125.45.100: bytes=32 time=44ms TTL=234

Ping statistics for 74.125.45.100:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 44ms, Maximum = 66ms, Average = 55ms

C:\temp>echo %errorlevel%
0
----------------------------------------

Then I tried the following in python (2.6.1)

---script---
import subprocess
import sys


try:
retcode = subprocess.call(["ping","019293.com"])
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e

try:
retcode = subprocess.call(["ping","google.com"])
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e


try:
retcode = subprocess.call(["c:/glassfish/bin/asadmin.bat","list-
system-properties","Instance-01"], shell=False)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e

try:
retcode = subprocess.call(["c:/glassfish/bin/asadmin.bat","list-
system-properties","Instance-05"], shell=False)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e
---script---

Executed Output:

---output---
C:\temp>c:\Python26\python.exe example2.py
Ping request could not find host 019293.com. Please check the name and
try again.
Child returned 1

Pinging google.com [74.125.67.100] with 32 bytes of data:

Reply from 74.125.67.100: bytes=32 time=244ms TTL=239
Reply from 74.125.67.100: bytes=32 time=244ms TTL=239
Reply from 74.125.67.100: bytes=32 time=191ms TTL=234
Reply from 74.125.67.100: bytes=32 time=59ms TTL=239

Ping statistics for 74.125.67.100:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 59ms, Maximum = 244ms, Average = 184ms
Child returned 0

....glassfish properties for Instance-01 display here...
Command list-system-properties executed successfully.
Child returned 0

Cannot determine type for target : Instance-05
CLI137 Command list-system-properties failed.
Child returned 0

C:\temp>
---output---

Notice how python never gets the correct returncode from asadmin.bat
but I can get the correct returncode from the shell every time. Can
anyone tell me why Python wouldn't be able to get the correct
returncode for asadmin?

TIA,

Andrew
 
M

Mark Hammond

Notice how python never gets the correct returncode from asadmin.bat
but I can get the correct returncode from the shell every time. Can
anyone tell me why Python wouldn't be able to get the correct
returncode for asadmin?

I think the problem will be that cmd.exe doesn't return the exit code to
*its* caller correctly. You can often work around this by avoiding the
use of cmd.exe to spawn the child process, but obviously you do need it
with a .bat file. I'm not aware of an easy work-around.

Cheers,

Mark
 
A

Andrew

En Thu, 05 Feb 2009 17:34:29 -0200, Andrew <[email protected]>  
escribió:


I've tried this several ways now. It seems to be something specific
with python and asadmin.bat.
I've tried the following manually in the cmd.exe prompt:

[examples showing %ERRORLEVEL% correctly set when running from the command  
line, but subprocess.call doesn't get it]
Notice how python never gets the correct returncode from asadmin.bat
but I can get the correct returncode from the shell every time. Can
anyone tell me why Python wouldn't be able to get the correct
returncode for asadmin?

The last exit code set by a command *should* propagate as the exit code of  
the whole .bat, then as the exit code of the cmd.exe instance that runs  
it, and finally Python *should* receive that value. Some old Windows  
versions didn't behave like that, but AFAIK XP does the right thing here.
Unless asadmin.bat is playing tricks with %ERRORLEVEL% or something.
Can you post the contents of asadmin.bat?

Without looking into it, I can think of a few alternatives:

- rewrite asadmin.bat in Python, if feasible. Some scripts just check/set  
a few environment variables and execute some process at the end, and  
that's all; in this case it should be easy to emulate the same thing in  
Python.

- try using another layer of your own, e.g., my_asadmin.bat:

call asadmin.bat %*
exit /b %ERRORLEVEL%

- variation: write the exit code somewhere:

call asadmin.bat %*
echo %ERRORLEVEL% > asadmin.err

and read asadmin.err from Python. (I've used something like this in a  
chain Win32 process --> 16 bits GUI application --> .bat script --> old  
DOS executable)

Thanks Gabriel,

Someone on the glassfish forums also pointed out the "exit /B
%ERRORLEVEL%" for the bottom of the batch file and that corrected the
issue for me. As well as not using that and removing "endlocal" which
I admit I have no clue what that does. Removing endlocal seems to
cause the batch script to pass out the correct returncode.

Thanks everyone for your input and assistance =]

Andrew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top