rodee
rodee

Reputation: 3151

call python function from shell and get only the returned value

How to get only the returned value from a function, in the below example, I want to get only foorbar and not this is a test in the bash shell.

$ cat foo.py
print "this is a test"
def bar():
    return "foobar"

$ output=$(python -c 'import foo;print foo.bar()')
$ echo $output
this is a test foobar

Upvotes: 0

Views: 188

Answers (3)

Robᵩ
Robᵩ

Reputation: 168626

In your specific case, where the desired output is the final line of the python's stdout, you can use tail:

output=$(python -c 'import foo;print foo.bar()' | tail -1)

Upvotes: 0

heemayl
heemayl

Reputation: 42007

If you want to keep the module as-is and get what you want, you need to suppress the module level string being printed by temporarily redirecting the STDOUT to someplace else (e.g. None, /dev/null or any other file descriptor as a dumping zone), and duplicate again to the original STDOUT once the import is done.

% cat spam.py
print("this is a test")
def bar():
    return "foobar"

% python3 -c 'import sys;sys.stdout=None;import spam;sys.stdout=sys.__stdout__;print(spam.bar())'
foobar

% out=$(python3 -c 'import sys;sys.stdout=None;import spam;sys.stdout=sys.__stdout__;print(spam.bar())')

% echo "$out"
foobar

Expanded form:

import sys
sys.stdout = None
import spam
sys.stdout = sys.__stdout__
print(spam.bar())

Upvotes: 1

Luke
Luke

Reputation: 119

I'd recommend if you require for whatever reason the print "this is a test" section, you check if the file is being run itself, such as by checking the __name__ property as follows:

foo.py:

def bar():
    return "foobar"

if __name__ == "__main__":
    print("this is a test")

This should mean that the only time "this is a test" is printed is when you call python foo.py, and not when foo is imported as a module. Hope this helps!

Upvotes: 2

Related Questions