3

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?

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

2 Comments

Yes your implementation is what I was looking for , however How can I capture this sys.stderr in a variable . Because I need to sore this in a variable so that I can use the value later.
@Nepal12 I've added some more info to my answer, I hope it helps.
0

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

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.