0

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
asked Feb 9, 2018 at 18:41
1
  • .... suppress stdout, then re-enable it only for that function call maybe? Commented Feb 9, 2018 at 18:44

3 Answers 3

2

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!

answered Feb 9, 2018 at 18:54
Sign up to request clarification or add additional context in comments.

1 Comment

in my case, I cannot modify foo.py, as its coming from different team, so I will have to do something from shell. thanks for the reply.
1

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())
answered Feb 9, 2018 at 18:52

4 Comments

Ooh, I didn't realize that you could use None for sys.stdout without complaint from Python.
@kindall Funny thing is I also come to know this today :)
Well, since this obviates the need for my answer, I'll at least share my one-liner to create a dummy file-like class with a write method that doesn't do anything: sys.stdout = type("DummyStdout", (object,), {"write": lambda self, s: None})()
Thanks, but foo.py was written for python2, so it throws some error with python3, any solution with python2 is appreciated. thanks again.
0

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)
answered Feb 9, 2018 at 19:03

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.