0

I have a simple Python script which will execute a shell script using subprocess mdoule in Python.

Below is my Python shell script which is calling testing.sh shell script and it works fine.

import os
import json
import subprocess

jsonData = '{"pp": [0,3,5,7,9], "sp": [1,2,4,6,8]}'
jj = json.loads(jsonData)

print jj['pp']
print jj['sp']

os.putenv( 'jj1',  'Hello World 1')
os.putenv( 'jj2',  'Hello World 2')
os.putenv( 'jj3', ' '.join( str(v) for v in jj['pp']  ) )
os.putenv( 'jj4', ' '.join( str(v) for v in jj['sp']  ) )

print "start"
subprocess.call(['./testing.sh'])
print "end"

And below is my shell script -

#!/bin/bash

for el1 in $jj3
do
    echo "$el1"
done

for el2 in $jj4
do
    echo "$el2"
done

for i in $( david ); do
    echo item: $i
done

Now the question I have is -

if you see my Python script, I am printing start, then executing shell script and then printing end.. So suppose for whatever reason that shell script which I am executing has any problem, then I don't want to print out end.

So in the above example, shell script will not run properly as david is not a linux command so it will throw an error. So how should I see the status of entire bash shell script and then decide whether I need to print end or not?

I have just added a for loop example, it can be any shell script..

Is it possible to do?

3 Answers 3

1

You can check stderr of the bash script rather than return code.

proc = subprocess.Popen('testing.sh', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
if stderr:
   print "Shell script gave some error"
else:
   print "end" # Shell script ran fine.
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Aro, It worked fine.. But I don't see any output of my shell script.. As you can see I have couple of echo command in my shell script.. Does it mean my shell script commands are getting executed but it is not getting printed out?
Your output is in variable - stdout. If you want to be displayed on screen, you can use stdout=subprocess.STDOUT
Thanks Aro: So I can safely assume that my shell script are getting executed but the results are getting stored in the stdout variable? correct?
1

Just use the returned value from call():

import subprocess

rc = subprocess.call("true")
assert rc == 0 # zero exit status means success
rc = subprocess.call("false")
assert rc != 0 # non-zero means failure

You could use check_call() to raise an exception automatically if the command fails instead of checking the returned code manually:

rc = subprocess.check_call("true") # <-- no exception
assert rc == 0

try:
    subprocess.check_call("false") # raises an exception
except subprocess.CalledProcessError as e:
    assert e.returncode == 1
else:
    assert 0, "never happens"

Comments

0

Well, according to the docs, .call will return the exit code back to you. You may want to check that you actually get an error return code, though. (I think the for loop will still return a 0 code since it more-or-less finished.)

2 Comments

Thanks tabstop. Can you provide an example in which shell script will failed and exit status is returned as 1 instead of 0.. Just trying to understand how it will work out.
By default, a shell script will return the status of its last command. Off the top of my head, a for loop will return the status of the last inner command or, if the loop didn't run at all (as in this case), a 0 for success. So if you change things so that the error happened last; or if you put an explicit return 1 in the script, you will see a 1 instead of a 0.

Your Answer

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