Reputation: 65
I'm building a script in python, and one part of it needs to send an email with a file as the message body. Instead of sending the contents of the file, the script sends me the next character entered into the terminal e.g. if I enter c as a part of "cat", it doesn't put c into the terminal, but instead sends me an email with "c" as the body.
This is on CentOS 7.6.1810, with Python 3.5.6.
#!/usr/src/Python-3.5.6/python
import subprocess
import sys
import os
subprocess.Popen(["mail", "-s", "Test Subject", "[email protected]", "<", "/path/to/file.txt"], stdout=open('stdout', 'w'), stderr=open('errout', 'w'))
The contents of file.txt should be send as the body, but I just get the first letter of whatever the next thing I type is. "stdout" reads "EOT" after this, and nothing is printed to "errout". To be clear, I'm trying to invoke the command
mail -s "Test Subject" [email protected] < /path/to/file.txt
from inside of the script. This command works as expected outside of the Python script, but inside of it I run into the problem.
Upvotes: 2
Views: 225
Reputation: 4681
subprocess.Popen()
executes your new process directly by default. So your code passes some additional arguments <
and /path/to/file.txt
to the mail
executable, which will not yield the expected result.
Redirections like <
on unix systems are handled by the shell, not by each individual executable. That's why you want subprocess.Popen()
to run your mail
command with all the arguments mail
as well as the redirection < /path/to/file.txt
in a shell instead.
You can do this with the shell=True
parameter:
subprocess.Popen(["mail", "-s", "Test Subject", "[email protected]", "<", "/path/to/file.txt"], stdout=open('stdout', 'w'), stderr=open('errout', 'w'), shell=True)
Note that the shell is probably not necessary – you could have Popen
open the file and connect mail
's stdin
to that descriptor, see anishsane's comment below.
Using a shell should be avoided especially if user data is being passed to the child process, as it would need to be sanitized properly to prevent command injection attacks.
See the Python 3 docs on subprocess.Popen.
Upvotes: 3