Return Value from Python-Shell as Response

return value from python script to shell script

You can't return message as exit code, only numbers. In bash it can accessible via $?. Also you can use sys.argv to access code parameters:

import sys
if sys.argv[1]=='hi':
print 'Salaam'

in shell:

# script for tesing
echo "............script started............"
sleep 1
result=`python python/ "hi"`
if [ "$result" == "Salaam" ]; then
echo "script return correct response"

Assign return value from python method to a variable in bash script

When you run this:

password_check=$(python $password)

You are assigning the output of the program to the password_check variable. The problem is that your program doesn't produce any output: in fact, it never even runs the passwordCheck function, because your Python script never calls passwordCheck. Do make things work the way you're trying to use the script, you would need to modify it to (a) actually call the passwordCheck method and (b) print output instead of returning a value:

import re, sys
password = sys.argv[1]
def passwordCheck():
if re.match(r'(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z])(?=.*[^A-Za-z0-9]).{14,}', password):
print 'okay'
return True
print 'fail'
return False


And then check for that value in your shell script:


password_check=$(python $password)
if [ "$password_check" == "okay" ];then
echo "Correct"
echo "Incorrect"

Note that Python doesn't require a terminal ; on lines, so instead

return False;

You should write:

return False

Additionally, in this example we're using the output of the script
to determine success/failure. A slightly more robust solution is to
use the exit code of the script instead. You can probably find a
variety of examples of using this technique if you explore online a

Grab return value from python with Shell Script



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.

import sys

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

In Bash:

$ outputString=$(python;echo "ok";echo "$outputString"


this is sent to stderr
this is sent to stdout

Here's a version of 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 "", is to redirect stderr in Bash to a file:

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

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

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


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

store return value of a Python script in a bash script

sys.exit(myString) doesn't mean "return this string". If you pass a string to sys.exit, sys.exit will consider that string to be an error message, and it will write that string to stderr. The closest concept to a return value for an entire program is its exit status, which must be an integer.

If you want to capture output written to stderr, you can do something like

python yourscript 2> return_file

You could do something like that in your bash script

output=$((your command here) 2> &1)

This is not guaranteed to capture only the value passed to sys.exit, though. Anything else written to stderr will also be captured, which might include logging output or stack traces.


print "something"

va=$(python 2>&1)                                                                                                                    
mkdir $va



Not sure why but in that case, I would write a main script and two other scripts... Mixing python and bash is pointless unless you really need to.

import script1
import script2

if __name__ == '__main__':
filename =

How to access python return value from bash script

Add a proper exit code from your script using the sys.exit() module. Usually commands return 0 on successful completion of a script.

import sys

def main():
print ("exec main..")

and capture it in shell script with a simple conditional. Though the exit code is 0 by default and need not be passed explicitly, using sys.exit() gives control to return non-zero codes on error cases wherever applicable to understand some inconsistencies with the script.

if python 2>&1 >/dev/null; then
echo 'script ran fine'

Capture return value from python script in command line

If the return value (which is unclear in the question) is a single line of output you could simply:

./ | tail -n 1

This will output the last line generated from the script (adjust the number as needed).

If you want to save to a file either > to create a new file, or >> to append to a file:

./ | tail -n 1 > file 

Best way to return a value from a python script

If you want your script to return values, just do return [1,2,3] from a function wrapping your code but then you'd have to import your script from another script to even have any use for that information:

Return values (from a wrapping-function)

(again, this would have to be run by a separate Python script and be imported in order to even do any good):

import ...
def main():
# calculate stuff
return [1,2,3]
Exit codes as indicators

(This is generally just good for when you want to indicate to a governor what went wrong or simply the number of bugs/rows counted or w/e. Normally 0 is a good exit and >=1 is a bad exit but you could inter-prate them in any way you want to get data out of it)

import sys
# calculate and stuff

And exit with a specific exit code depending on what you want that to tell your governor.
I used exit codes when running script by a scheduling and monitoring environment to indicate what has happened.

(os._exit(100) also works, and is a bit more forceful)

Stdout as your relay

If not you'd have to use stdout to communicate with the outside world (like you've described).
But that's generally a bad idea unless it's a parser executing your script and can catch whatever it is you're reporting to.

import sys
# calculate stuff
sys.stdout.write('Bugs: 5|Other: 10\n')

Are you running your script in a controlled scheduling environment then exit codes are the best way to go.

Files as conveyors

There's also the option to simply write information to a file, and store the result there.

# calculate
with open('finish.txt', 'wb') as fh:

And pick up the value/result from there. You could even do it in a CSV format for others to read simplistically.

Sockets as conveyors

If none of the above work, you can also use network sockets locally *(unix sockets is a great way on nix systems). These are a bit more intricate and deserve their own post/answer. But editing to add it here as it's a good option to communicate between processes. Especially if they should run multiple tasks and return values.

Running shell command and capturing the output

In all officially maintained versions of Python, the simplest approach is to use the subprocess.check_output function:

>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'

check_output runs a single program that takes only arguments as input.1 It returns the result exactly as printed to stdout. If you need to write input to stdin, skip ahead to the run or Popen sections. If you want to execute complex shell commands, see the note on shell=True at the end of this answer.

The check_output function works in all officially maintained versions of Python. But for more recent versions, a more flexible approach is available.

Modern versions of Python (3.5 or higher): run

If you're using Python 3.5+, and do not need backwards compatibility, the new run function is recommended by the official documentation for most tasks. It provides a very general, high-level API for the subprocess module. To capture the output of a program, pass the subprocess.PIPE flag to the stdout keyword argument. Then access the stdout attribute of the returned CompletedProcess object:

>>> import subprocess
>>> result =['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'

The return value is a bytes object, so if you want a proper string, you'll need to decode it. Assuming the called process returns a UTF-8-encoded string:

>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'

This can all be compressed to a one-liner if desired:

>>>['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'

If you want to pass input to the process's stdin, you can pass a bytes object to the input keyword argument:

>>> cmd = ['awk', 'length($0) > 5']
>>> ip = 'foo\nfoofoo\n'.encode('utf-8')
>>> result =, stdout=subprocess.PIPE, input=ip)
>>> result.stdout.decode('utf-8')

You can capture errors by passing stderr=subprocess.PIPE (capture to result.stderr) or stderr=subprocess.STDOUT (capture to result.stdout along with regular output). If you want run to throw an exception when the process returns a nonzero exit code, you can pass check=True. (Or you can check the returncode attribute of result above.) When security is not a concern, you can also run more complex shell commands by passing shell=True as described at the end of this answer.

Later versions of Python streamline the above further. In Python 3.7+, the above one-liner can be spelled like this:

>>>['ls', '-l'], capture_output=True, text=True).stdout
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'

Using run this way adds just a bit of complexity, compared to the old way of doing things. But now you can do almost anything you need to do with the run function alone.

Older versions of Python (3-3.4): more about check_output

If you are using an older version of Python, or need modest backwards compatibility, you can use the check_output function as briefly described above. It has been available since Python 2.7.

subprocess.check_output(*popenargs, **kwargs)  

It takes takes the same arguments as Popen (see below), and returns a string containing the program's output. The beginning of this answer has a more detailed usage example. In Python 3.5+, check_output is equivalent to executing run with check=True and stdout=PIPE, and returning just the stdout attribute.

You can pass stderr=subprocess.STDOUT to ensure that error messages are included in the returned output. When security is not a concern, you can also run more complex shell commands by passing shell=True as described at the end of this answer.

If you need to pipe from stderr or pass input to the process, check_output won't be up to the task. See the Popen examples below in that case.

Complex applications and legacy versions of Python (2.6 and below): Popen

If you need deep backwards compatibility, or if you need more sophisticated functionality than check_output or run provide, you'll have to work directly with Popen objects, which encapsulate the low-level API for subprocesses.

The Popen constructor accepts either a single command without arguments, or a list containing a command as its first item, followed by any number of arguments, each as a separate item in the list. shlex.split can help parse strings into appropriately formatted lists. Popen objects also accept a host of different arguments for process IO management and low-level configuration.

To send input and capture output, communicate is almost always the preferred method. As in:

output = subprocess.Popen(["mycmd", "myarg"], 


>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out

If you set stdin=PIPE, communicate also allows you to pass data to the process via stdin:

>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo\nfoofoo\n')
>>> print out

Note Aaron Hall's answer, which indicates that on some systems, you may need to set stdout, stderr, and stdin all to PIPE (or DEVNULL) to get communicate to work at all.

In some rare cases, you may need complex, real-time output capturing. Vartec's answer suggests a way forward, but methods other than communicate are prone to deadlocks if not used carefully.

As with all the above functions, when security is not a concern, you can run more complex shell commands by passing shell=True.


1. Running shell commands: the shell=True argument

Normally, each call to run, check_output, or the Popen constructor executes a single program. That means no fancy bash-style pipes. If you want to run complex shell commands, you can pass shell=True, which all three functions support. For example:

>>> subprocess.check_output('cat books/* | wc', shell=True, text=True)
' 1299377 17005208 101299376\n'

However, doing this raises security concerns. If you're doing anything more than light scripting, you might be better off calling each process separately, and passing the output from each as an input to the next, via

run(cmd, [stdout=etc...], input=other_output)


Popen(cmd, [stdout=etc...]).communicate(other_output)

The temptation to directly connect pipes is strong; resist it. Otherwise, you'll likely see deadlocks or have to do hacky things like this.

Related Topics

Leave a reply