11

I enjoy using unix commands very much, but I came to the point, where I would find embedded python parts useful. This is my code:

#!/bin/bash -
echo "hello!";

exec python <<END_OF_PYTHON
#!/usr/bin/env python

import sys

print ("xyzzy")

sys.exit(0)
END_OF_PYTHON

echo "goodbye!";

However, only "hello" gets printed.

$ ./script.sh 
hello!
xyzzy

How can I modify the bash script to fully embedd python? And would it then be possible to pass values from python variables into bash variables? Thanks a lot.

6
  • You mean only hello, and xyzzy get printed? Commented Mar 5, 2014 at 17:02
  • 2
    You don't need the #!; you are explicitly calling python. Commented Mar 5, 2014 at 17:04
  • @JayanthKoushik exactly Commented Mar 5, 2014 at 17:13
  • Subquestion, what would then be proper way of passing value/multiple values from python variables to bash variables? In my case, after embedded python script is over, I need to use values from two python variables in subsequent part of bash script. Commented Mar 5, 2014 at 17:20
  • @Perlnika, that should really be an entirely separate question; there's not a single easy answer to it. Commented Mar 5, 2014 at 17:37

5 Answers 5

14

On the exec python ... line, you're exec()ing the Python interpreter on your PATH, so the python image will replace the bash image, and there is absolutely no hope of the echo "goodbye!" ever being executed. If that's what you want, that's fine, but otherwise, just omit the exec.

The shebang (“#!”) line in the python code is completely unnecessary. When you try to run an ordinary file, the kernel sees the “#!”, runs whatever follows it (/usr/bin/env python), and feeds the rest of the file to the stdin of whatever has been run. This is a general facility used to invoke interpreters. Since you are invoking the python interpreter yourself, not asking the kernel to do it, this is neither needed nor useful.

The sys.exit(0) is also unnecessary, since the Python interpreter will naturally exit when it gets to the end of its input (at END_OF_PYTHON) anyway. This means that the import sys is also unnecessary.

In summary, the following is what I would write to achieve what you appear to want to achieve:

#!/bin/bash
echo "hello!";

python <<END_OF_PYTHON
print ("xyzzy")
END_OF_PYTHON

echo "goodbye!";
Sign up to request clarification or add additional context in comments.

Comments

10

Don't use exec. That replaces the shell process with the program you're running, so the rest of the script doesn't execute.

#!/bin/bash -
echo "hello!";

python <<END_OF_PYTHON
#!/usr/bin/env python

import sys

print ("xyzzy")

sys.exit(0)
END_OF_PYTHON

echo "goodbye!";

Comments

6

Don't use exec python, just use python.

The exec tells the shell to replace itself with the Python interpreter, so it's no longer running after that point.

Comments

1

Others have answered your specific issue, but in answer to the general question "How to mix bash with python", Xonsh may be useful to you. It's a special shell that allows you to use python and bash side-by-side. There's also sultan if you want to be able to easily call bash from python.

Comments

0

Or maybe utilizing the commenting and quoting feature of both language:

''':'
# bash code below
echo 'hello world (I am bash) !'

python $0
exit 0 # 'exit' is necessary.
#'''

# python code below
import os, sys
print("hello world (I am python) !")

Output:

bash-3.1$ ./bash-with-python
hello world (I am bash) !
hello world (I am python) !

Comments

Your Answer

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.