Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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

And below is my testing.sh 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 out start and then executing my shell script, if there are any errors in executing my shell script, then it won't print out end. In the above example, it won't print out end as there is an error.

  1. Firstly, So is this the right way to do this kind of problem? Basically, I want to print start first and if the shell script got executed successfully, then I want to print end. But if for whatever reason, my shell script doesn't got executed successfully, then I won't print out end.
  2. Secondly, with this approach, I cannot see my echo statement getting printed out on the console from the shell script? Does it mean, my shell script are getting executed but it is not getting printed out on the console somehow?
  3. Thirdly, Is there any possibility of extracting the error message from the shell script, meaning whatever was the reason of shell script getting failed?
share|improve this question
    
1. Because you print "end" in the else clause. 2. Because you pipe the shell script's stderr and stdout to your script, they're now in your variables stderr and stdout. If you want to see them on the console, print them from your Python script. 3. Extract any error messages from the variable stderr. –  Lukas Graf Dec 27 '13 at 6:47
    
So that means, my shell scripts are getting executed and all the output results are getting stored in stdout and error in stderr? –  Webby Dec 27 '13 at 7:33
    
Exactly. You might have to pass shell=True as a keyword argument OR call your script with ['/bin/bash', 'testing.sh'] though. –  Lukas Graf Dec 27 '13 at 8:03
    
@LukasGraf: Thanks for suggestion. And why you are suggesting you use shell=True and call my script like this ['/bin/bash', 'testing.sh']. Is there any advantage of doing this way? I can execute the shell script like the way I have in my above question. –  Webby Dec 27 '13 at 18:34
    
Because I'm pretty sure that interpreting the #!/bin/bash shebang is a function of the shell executing a script. I actually have no idea why it works without shell=True or calling the interpreter binary with the script as an argument. –  Lukas Graf Dec 27 '13 at 18:43
add comment

1 Answer

up vote 1 down vote accepted

1. Yes, it seems like your code matches your intention.

2. Correct. Because you used stdout=subprocess.PIPE and stderr=subprocess.PIPE, you will see no output on the console from your bash script. However, the output to stdout and stderr are captured on the next line in your variables stdout and stderr when you call communicate().

3. Yes, and you already did it: Just check the contents of your stderr variable, it will hold all error messages that were printed by your shell script.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.