
Originally Posted by
purpleflame
So now I am trying to use subprocess instead of os, but it tells me:
Code:
'file' object has no attribute 'communicate'
[...]
I am not sure why it is going to file and not sendmail since that is what MAIL has in it. Am I supposed to use send_signal rather than communicate?
That's because in your code, you set "p" to the process's stdin, which makes it a file (note the error message tells you this), not the process (a Popen). You use the 'write' method on files, 'communicate' on Popen objects. If ever you're getting an "object has no attribute" error, it's probably because a variable doesn't hold what you think it holds.
Signals are a very basic IPC mechanism. You can only send 32 asynchronous messages (most with predefined meanings; older systems had fewer signals). If a process is handling a signal, it can't receive any more signals of the same type. Moreover, receiving a signal while handling another can cause problems (depending on how you've set up signal handling). In short, no, don't use send_signal.
Also, there's no need to pass arguments with default values to a function when you're using keyword arguments.
Try this:
Code:
#!/usr/bin/env python
print "Content-type: text/plain"
print
import os, subprocess, datetime
mailer = "/usr/sbin/sendmail"
def readmsg(fname='../sampleemail.txt'):
msgfile = open(fname, 'r')
msg = msgfile.read()
msgfile.close()
return msg + datetime.datetime.now().__str__() + "\n"
# Open a pipe to the mail program and write the data to the pipe.
def sendmail(msg):
p=subprocess.Popen([mailer,"-t"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p.stdin.write(msg)
p.stdin.close();
return (p.returncode, p.stdout.read())
try:
print "Using", mailer
# Read the email message from a file.
msg = readmsg();
print "Sending {\n", msg, "}"
(returncode, rsltmsg) = sendmail(msg)
if returncode:
print "Sendmail failed with code", returncode
if len(rsltmsg):
print "Sendmail had this to say:", rsltmsg
except IOError, exc:
print "Error creating message:", exc
except Exception, exc:
print 'Error while mailing', exc
You'll want to refactor to get rid of the "mailer" global, either by creating a class or using closures (examples of closures).
Edit:
Don't forget to move sampleemail.txt & update the script.