embedding short python scripts inside a bash script

Solution 1:

Why should you need to use -c? This works for me:

python << END
... code ...
END

without needing anything extra.

Solution 2:

The python interpreter accepts - on the command line as a synonym for stdin so you can replace the calls to pyexec with:

python - <<END

See command line reference here.

Solution 3:

One problem with using bash here document is that the script is then passed to Python on stdin, so if you want to use the Python script as a filter, it becomes unwieldy. One alternative is to use the bash's process substitution, something like this:

... | python <( echo '
code here
' ) | ...

If the script it too long, you could also use here document inside the paren, like this:

... | python <(
cat << "END"
code here
END
 ) | ...

Inside the script, you can read/write as you normally would from/to standard i/o (e.g., sys.stdin.readlines to gobble up all the input).

Also, python -c can be used as mentioned in other answers, but here is how I like to do it to format nicely, while still respecting Python's indentation rules (credits):

read -r -d '' script <<-"EOF"
    code goes here prefixed by hard tab
EOF
python -c "$script"

Just make sure that the first character of each line inside here document is a hard tab. If you have to put this inside a function, then I use the below trick that I saw somewhere to make it look aligned:

function somefunc() {
    read -r -d '' script <<-"----EOF"
        code goes here prefixed by hard tab
----EOF
    python -c "$script"
}

Solution 4:

Sometimes it is not a good idea to use here document. Another alternative is to use python -c:

py_script="
import xml.etree.cElementTree as ET,sys
...
"

python -c "$py_script" arg1 arg2 ...

Solution 5:

If you need to use the output of the python in the bash script you can do something like this:

#!/bin/bash

ASDF="it didn't work"

ASDF=`python <<END
ASDF = 'it worked'
print ASDF
END`

echo $ASDF