-1

I have a python script that is called by a korn shell script. If the python script runs into an error, the korn shell script still exits with 0. How to a get the python script to tell the ksh that it didn't terminate correctly?

The rapper script looks like this:

python2.7 python_script.py ${inargument} >> ${log_file}  2>&1

exit_code=$?                             

if [ ${exit_code} -ne 0 ]
   then
   echo "Python script failed" >> ${log_file}
fi
16
  • 1
    In shell script you can do echo "Returncode=$?" Commented Apr 19, 2016 at 18:16
  • 1
    @AlexKinman, that looks fine on the shell side. To test, try replacing python2.7 python_script.py with python2.7 -c 'raise Exception("foo")' -- if your shell script suddenly sees a nonzero exit status, you know it's the Python code that's masking the true exit status. Commented Apr 19, 2016 at 21:42
  • 1
    @AlexKinman, ...well, "fine" is a stretch; it's bad practice to capture exit status when that's all you're testing; it's better practice to write that like so: if ! python2.7 python_script.py ...; then echo "Python script failed"; fi, not capturing $? at all. But if the Python script is masking its exit status, that won't work either. Commented Apr 19, 2016 at 21:44
  • 1
    Voting to close as unreproducible. A standard Python installation returns a non-zero exit status on exception. python -c 'raise ValueError("boom"); echo $? prints 1 and python -c 'import time; time.sleep(3600)' when interrupted by ctrl-C likewise returns an exit status of 1. Perhaps your python2.7 command is an incompetently written wrapper which discards the exit status. Commented Apr 20, 2016 at 4:26
  • 1
    I'm not sure that there's content here that isn't covered more tersely and directly in answers to narrower questions (and which is thus likely to be easier to find by folks it's of interest to). For instance, stackoverflow.com/questions/14259660/…; stackoverflow.com/questions/25728287/…; etc. Commented Apr 22, 2016 at 2:53

3 Answers 3

4

I'm not sure about KSH, but this is how you get python to return a non-zero return value, I assume KSH can detect and deal with that.

import sys

retCode = 5
sys.exit(retCode)

or

retCode = -128
raise SystemExit(retCode)
Sign up to request clarification or add additional context in comments.

3 Comments

-128 isn't valid here -- it's unsigned single-byte integers only, so this will be converted to something else rather than returned intact.
...also, ksh's behavior is precisely the same as that of any other POSIX-compliant shell in this respect, populating $? with the prior command's exit status.
(as an aside, see man 3 sysexits for a list of conventional exit status codes; custom values should, by convention, be below the EX__BASE constant of 64 -- and, for an erroneous status, above 0 (the EXIT_SUCCESS constant defined in C99).
0

Wrap your whole script in a try block and in catch write the error to an out put file. Than in your ksh you can go read that output file and do what ever it is you need to do.

here is some pseudo code.

rm opFile
python yourSript.py
if opFile != blank:
   process log file... 
   start cat runlog.m | more

4 Comments

Oh this didn't work for you?
I can't speak for the first downvoter, but speaking for myself, it's not a question of whether or not it works: There's a standard-practice way to do this, and ignoring that convention (defined in the C99 standard, in the POSIX standard, and elsewhere) for no good reason is... well, not good practice.
+ @nephlm provided the best answer, in a use case where ksh wants to use python to fail gracefully, potentially trying multiple things before failing, creating a runlog file that documents the path through the execution is standard practice as far as I know... (The thing is I don't know.)
Yes, logging is standard practice. No, using that logged content in place of exit status is not standard practice.
0

I could not comment because of reputation, but you absolutely could use the code from nephim comment.

1) just put the first of nephim's code in test.py (chmod 700 test.py)

2) this ksh script run test.py :

#!/usr/bin/ksh

./test.py

exit $?

3) And this is example from command line

> ./test.ksh 
> echo $?
5

P.S.: You should chmod 700 test.ksh as well.

P.P.S : Probably I misunderstood your question. If your python script exits before it reach the end (and so it don't execute sys.exit(codeRet) command), in this case you should use try..execpt construction.

try :
    <some code>
except <Error to Catch>:
    sys.exit(codeRet)

As explained here : Python: about catching ANY exception you could even catch all of exceptions :

try:
    do_something()
except:
    print "Caught it!"

But as explained : "You can but you shouldn't"

Update: @AlexKinman I think there is some problem with your python... as mentioned by tripleee could it be some wrapper? Could you give a return of which python2.7

Here my tests :

$# cat wrong_test.ksh

#!/bin/ksh

log_file=log.txt

python -c 'raise Exception("foo")' >> ${log_file}  2>&1

exit_code=$?                             

if [ ${exit_code} -ne 0 ]
   then
   echo "Python script failed" >> ${log_file}
fi

$# cat log.txt Traceback (most recent call last): File "", line 1, in Exception: foo Python script failed

$# cat good_test.ksh

#!/bin/ksh

log_file=log1.txt

python -c 'print "Hello"' >> ${log_file}  2>&1

exit_code=$?                             

if [ ${exit_code} -ne 0 ]
   then
   echo "Python script failed" >> ${log_file}
fi

$# cat log1.txt
Hello

10 Comments

If the interpreter exits due to an exception, it'll have a nonzero exit status by default -- you don't need to catch that and call sys.exit() yourself.
...you can test this yourself easily: python -c 'raise Exception("foo")'; echo $?
@CharlesDuffy the problem I am not getting the nonzero default exit status. When I run the code in my python interpreter, I get an error if I pass the wrong input arguments. But when I run in using the KSH, it doesn't pass anything to the KSH.
@CharlesDuffy... yes, you are right. In this light, catch all to send just sys.exit(1) does not make sens... Except of situation if you are using exit status 1 for something in your code. In this case it could be intresting to catch and send another status.
@CharlesDuffy I figured out the problem. The Python was working fine and the KSH was working fine, but another KSH downstream from it had a bug such that it was making my code look like it wasn't working correctly, when it actually was. Thanks for the help.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.