Nepal12
Nepal12

Reputation: 593

Grab return value from python with Shell Script

I am aware that a similar kind of question has already been asked and answered.
However, my question deals with a slightly different type of problem and implementation:

The situation is:
I need to build a shell script which will capture the return value of a python (2.7) script, which will then be used in a jenkins job.
In the python script, I have to read an SVN checkout text file and return the value of the file, update the value of the file, and commit it.

I have implemented the following code:

swdl_number_receiver.py

import posixpath
import os
import sys
import subprocess

SVN_VERSION_DIR_PATH = 'data'
SWDL_FILE_NAME = "swdl_number.txt"

# Exit codes
class ExitCode:
   """ Exit code Enumeration """
    SUCCESS = 0
    FAILURE = 1

# get SWDL number from the file
def getSWDLNumber():
work_dir = posixpath.join(os.getcwd(),SVN_VERSION_DIR_PATH)
version_number = None
new_version_number = None

# Read the File
os.chdir(work_dir)
with open(SWDL_FILE_NAME, "r") as input_file:
    for line in input_file:
        version_number = str.strip(line)
        if version_number is None:
            print "---- SWDL NUmber is empty existing the code ....... "
            sys.exit(ExitCode.FAILURE)
        else:
            print "++++ The found SWDL number is : " + version_number
            new_version_number = int(version_number) + 1
            print "++++ The New SWDL Number is  : " + str(new_version_number)

print "++++ Writing the new SWDL Number from " + str(version_number) + " to " + str(new_version_number)
#replace the file with new content
os.remove(SWDL_FILE_NAME)
with open(SWDL_FILE_NAME, 'wb') as output:
    output.write(str(new_version_number).rstrip('\n'))

checkin_message = '"Updated SWDL Number to : ' + str(new_version_number) + '"'
try:
    subprocess.call(['svn', 'commit', '-m ' + checkin_message, SWDL_FILE_NAME, '--non-interactive'])
except:
    sys.exit(ExitCode.FAILURE)

return new_version_number


if __name__ == "__main__":
    print getSWDLNumber()

In my shell script I am doing:

outputString=$(python swdl_number_receiver.py)
echo $outputString

The swdl_number.txt contains only one line with 5 digits.

My problem: When I comment out all the "print" lines and the try and catch for the SVN commit, I get only new_version_number as the return value.
In other words, If I uncomment all the lines with print statements and the try and catch block for SVN commit, then on the shell script as $output_string I get every print statements and the commit message as well as the "new_version_number". And If I comment out all the print statement and try and catch block then I am getting the desired "new_version_number".

How should my code be modified in order to get the only required "new_version_number" return, and display all print lines?

Upvotes: 3

Views: 8967

Answers (2)

PM 2Ring
PM 2Ring

Reputation: 55469

The

outputString=$(python swdl_number_receiver.py)

construction captures text sent to stdout. If you want your script to print information to the terminal then you can send it to stderr. Here's a simple demo.

qtest.py

import sys

print >>sys.stderr, "this is sent to stderr"
print "this is sent to stdout"

In Bash:

$ outputString=$(python qtest.py);echo "ok";echo "$outputString"

output

this is sent to stderr
ok
this is sent to stdout


Here's a version of qtest.py that works on Python 2 and Python 3:

from __future__ import print_function
import sys

print("this is sent to stderr", file=sys.stderr)
print("this is sent to stdout")

If you also want to capture the output sent to stderr in a variable, one way to do that, without changing "qtest.py", is to redirect stderr in Bash to a file:

$ outputString=$(python qtest.py 2>qtemp);echo "ok";stderrString=$(<qtemp);echo "STDOUT: $outputString";echo "STDERR: $stderrString"
ok
STDOUT: this is sent to stdout
STDERR: this is sent to stderr

A better way is to write directly to the file in Python:

qtest.py

from __future__ import print_function

with open("qtemp", "w") as f:
    print("this is sent to qtemp", file=f)
    print("this is sent to stdout")

bash

$ outputString=$(python qtest.py);echo "ok";qtempString=$(<qtemp);echo "STDOUT: $outputString";echo "qtemp: $qtempString"
ok
STDOUT: this is sent to stdout
qtemp: this is sent to qtemp

Upvotes: 1

Sanket Sudake
Sanket Sudake

Reputation: 771

Well, you can share your version file between python and bash. Depending on exit code of your python script you can decide whether you got valid new version.

Shell script:

# Version file name
SWDL_FILE_NAME="x.txt"
export SWDL_FILE_NAME
python swdl_number_receiver.py
# Exit code of python script
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ] ; then
        # If scripts exits successfully get version
        NEW_VERSION=$(cat $SWDL_FILE_NAME)
        echo "New version is $NEW_VERSION"
        exit 0
else
        # No new version
        echo "Failed to get new version"
        exit 1
fi

Minimal Python File:

import sys
import os
SWDL_FILE_NAME=os.environ['SWDL_FILE_NAME']
with open(SWDL_FILE_NAME, 'w') as fp:
    fp.write("111")
sys.exit(0)

Output:

$ ./myscript.sh 
New version is 111

Upvotes: 0

Related Questions