18

I need to include below python script inside a bash script.

If the bash script end success, I need to execute the below script:

#!/usr/bin/python    
from smtplib import SMTP
import datetime
debuglevel = 0

smtp = SMTP()
smtp.set_debuglevel(debuglevel)
smtp.connect('192.168.75.1', 25)
smtp.login('my_mail', 'mail_passwd')

from_addr = "My Name <my_mail@192.168.75.1>"
to_addr = "<my_mail@192.168.75.1"
subj = "Process completed"
date = datetime.datetime.now().strftime( "%d/%m/%Y %H:%M" )
#print (date)
message_text = "Hai..\n\nThe process completed."

msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n\n%s" % ( from_addr, to_addr, subj, date, message_text )

smtp.sendmail(from_addr, to_addr, msg)
smtp.quit()
4
  • 4
    script.sh && python script.py ?
    – Costas
    Feb 13, 2015 at 18:04
  • 2
    Why "include" it? Why not just run it?
    – terdon
    Feb 13, 2015 at 18:10
  • 1
    To call bash-script from python import os os.system ("./script.sh")
    – Costas
    Feb 13, 2015 at 18:17
  • python -c $(cat << EOF ... ... EOF )" More in my answer
    – nadapez
    Oct 6, 2021 at 19:40

7 Answers 7

35

Just pass a HereDoc to python -.

From python help python -h:

- : program read from stdin

#!/bin/bash

MYSTRING="Do something in bash"
echo $MYSTRING

python - << EOF
myPyString = "Do something on python"
print myPyString

EOF

echo "Back to bash"
4
  • 1
    I don't see why this was downvoted. It's a simple and workable solution for some cases. It does have the (major) limitation that you can't use standard input in the python script, though (since it's receiving stdin from the heredoc).
    – pyrocrasty
    Feb 11, 2017 at 9:01
  • 1
    I hate downvotes without comment. It works for me. Upvoted it ;-)
    – kev
    Mar 27, 2018 at 3:47
  • 3
    Upvoted this answer because (unlike the accepted answer) it doesn't write the script to the file system. Mar 28, 2020 at 9:16
  • look at my answer. I used the -c argument, not -. Note also that this is not very efficient, because the program is read and compiled line by line as it runs
    – nadapez
    Oct 6, 2021 at 19:34
20

You can use heredoc if you want to keep the source of both bash and python scripts together. For example, say the following are the contents of a file called pyinbash.sh:

#!/bin/bash

echo "Executing a bash statement"
export bashvar=100

cat << EOF > pyscript.py
#!/usr/bin/python
import subprocess

print 'Hello python'
subprocess.call(["echo","$bashvar"])

EOF

chmod 755 pyscript.py

./pyscript.py

Now running the pyinbash.sh will yield:

$ chmod 755 pyinbash.sh
$ ./pyinbash.sh
Exe
4
  • Per OP's comment to another answer, I updated my answer which takes care of bash variables in the python script. Feb 13, 2015 at 18:32
  • 1
    I can't get the variable's value from bash-script into python script. Mar 9, 2015 at 10:29
  • I replace subprocess.call(["echo","\$bashvar"]) into subprocess.call(["echo","bashvar"]) now it's working. Mar 9, 2015 at 10:35
  • That was pretty neat!
    – SexyBeast
    Jan 13, 2016 at 8:19
3

The simplest approach is to just save the python script as, for example script.py and then either call it from the bash script, or call it after the bash script:

#!/usr/bin/env bash
echo "This is the bash script" &&
/path/to/script.py

Or

script.sh && script.py
1
  • On the bash-script execution time some variables are get defined, I need this on the python script for the message body. Feb 13, 2015 at 18:23
3

This is old question, but maybe useful for someone. It's a way to include Python script inside a Bash script and use sys.stdin.

Extract Python script and run it with -c. The trick is to use a function, that allows use ' and " in the script. Also sys.stdin is available.

#!/bin/bash

read_file()
{
  local name="${1//./[.]}"
  sed -En '/^#---=== '"$name"' ===---$/,$ {/^#---=== '"$name"' ===---$/ n; /^#---===/ q; p; }' "$0"
}

echo Johny | python3 -c "$(read_file script.py)"
exit

#---=== script.py ===---
import sys
print('Your name is', sys.stdin.readline().strip())
#---===---
1

How about this for an example:

PYTHON_BIN=/usr/bin/python
if [ -x $PYTHON_BIN ]; then
$PYTHON_BIN -c "print 'Hello, world'"
else
echo 'Hello, world'
fi

VS

$ ./foobar.py
env: python: No such file or directory
2
1

I know this post is old, but I thought that I would share my code that is a working example.

#!/bin/bash
printf "This is BASH\n"
printf "Please enter some text: "; read ans
export ans

cat << EOF > pyscript.py
#!/usr/bin/python3 -tt
import subprocess

print('............This is Python')
subprocess.call(["echo","............$ans"])
print('............Done with Python')

EOF

chmod 770 pyscript.py

./pyscript.py

printf "This is BASH again\n"
exit 0
0
#/bin/bash
python3 -c "$(cat << EOF

a = input('?>')
print('you typed', a)
print('\033[1;32mbye...\033[m')

EOF
)            

This works. Th $() pass the output of the command inside (in this case cat) as the argument to python. There is no pipelining so std input can be used in the script.

this also works:

#/bin/bash

python3 -c "
a = input('?>') 
print('you typed', a)
print('\033[1;32mbye...\033[m')"

only that " cant be used in the script. If you needed it you should escape the " like this:

#/bin/bash

python3 -c "
a = input('?>') 
print(\"you typed\", a)
print(\"\033[1;32mbye...\033[m\")"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.