I swear I have seen this done before but can not find it now. Is it possible to have a shell script start a python interpeter "mid stream", ie:
#!/bin/bash
#shell stuff..
set +e
VAR=aabb
for i in a b c; do
echo $i
done
# same file!
#!/usr/bin/env python
# python would be given this fd which has been seek'd to this point
import sys
print ("xyzzy")
sys.exit(0)
5 Answers 5
You can use this shell syntax (it is called here document in Unix literature):
#!/bin/sh
echo this is a shell script
python <<@@
print 'hello from Python!'
@@
The marker after '<<' operator can by an arbitrary identifier, people often use something like EOF (end of file) or EOD (end of document). If the marker starts a line then the shell interprets it as end of input for the program.
Comments
If your python script is very short. You can pass it as a string to python using the -c option:
python -c 'import sys; print "xyzzy"; sys.exit(0)'
Or
python -c '
import sys
print("xyzzy")
sys.exit(0)
'
Comments
You could write
exec python <<END_OF_PYTHON
import sys
print ("xyzzy")
sys.exit(0)
END_OF_PYTHON
to replace the Bash process with Python and pass the specified program to Python on its standard input. (The exec replaces the Bash process. The <<END_OF_PYTHON causes standard input to contain everything up till END_OF_PYTHON.)
2 Comments
env. I suppose the command could be exec env python <<END_OF_PYTHON, but it's probably better just to remove the shebang.Of course right after I posted this I remembered a way to do it:
#!/bin/sh
echo Shell
python <<EOF
import sys
print "Python"
sys.exit(0)
EOF
Comments
I agree that mixing/mashing up can be quite a powerful technique - not only in scripting but also in command line (e.g. perl inliners have been proven to be very successful over time). So my small tip on another variation of one-liners (in addition to mentioned by kev) for mixed scripting in bash/python:
for VAR in $(echo 'import sys; print "x y z"; sys.exit(0)' | python -);do echo "$VAR"; done;
produces
x
y
z