user2467545
user2467545

Reputation:

How to check the status of a shell script using subprocess module in Python?

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?

Upvotes: 0

Views: 2527

Answers (3)

jfs
jfs

Reputation: 414325

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"

Upvotes: 1

Arovit
Arovit

Reputation: 3709

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.

Upvotes: 1

tabstop
tabstop

Reputation: 1761

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.)

Upvotes: 0

Related Questions