6

I'm hacking some support for DomainKeys and DKIM into an open source email marketing program, which uses a python script to send the actual emails via SMTP. I decided to go the quick and dirty route, and just write a perl script that accepts an email message from STDIN, signs it, then returns it signed.

What I would like to do, is from the python script, pipe the email text that's in a string to the perl script, and store the result in another variable, so I can send the email signed. I'm not exactly a python guru, however, and I can't seem to find a good way to do this. I'm pretty sure I can use something like os.system for this, but piping a variable to the perl script is something that seems to elude me.

In short: How can I pipe a variable from a python script, to a perl script, and store the result in Python?

EDIT: I forgot to include that the system I'm working with only has python v2.3

Alex Fort
  • 18,459
  • 5
  • 42
  • 51

6 Answers6

11

Use subprocess. Here is the Python script:

#!/usr/bin/python

import subprocess

var = "world"

pipe = subprocess.Popen(["./x.pl", var], stdout=subprocess.PIPE)

result = pipe.stdout.read()

print result

And here is the Perl script:

#!/usr/bin/perl

use strict;
use warnings;

my $name = shift;

print "Hello $name!\n";
Chas. Owens
  • 64,182
  • 22
  • 135
  • 226
9

os.popen() will return a tuple with the stdin and stdout of the subprocess.

millimoose
  • 39,073
  • 9
  • 82
  • 134
7
from subprocess import Popen, PIPE
p = Popen(['./foo.pl'], stdin=PIPE, stdout=PIPE)
p.stdin.write(the_input)
p.stdin.close()
the_output = p.stdout.read()
ngn
  • 7,763
  • 6
  • 26
  • 35
2

"I'm pretty sure I can use something like os.system for this, but piping a variable to the perl script is something that seems to elude me."

Correct. The subprocess module is like os.system, but provides the piping features you're looking for.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • I should have clarified that I'm only working with python 2.3, and it seems the subprocess module is for 2.4 and up. – Alex Fort Apr 28 '09 at 15:05
  • @Alex Fort: Just grab the subprocess module from 2.4 and run it on 2.3. It seems to work. – nosklo Apr 28 '09 at 15:41
2

I'm sure there's a reason you're going down the route you've chosen, but why not just do the signing in Python?

How are you signing it? Maybe we could provide some assitance in writing a python implementation?

Jon Cage
  • 36,366
  • 38
  • 137
  • 215
  • I *would* do the signing from python, but my python-fu is pretty weak. That would be a more optimal solution, however, so I may consider that in the future, especially if I decide to contribute the code to the community. – Alex Fort Apr 28 '09 at 15:21
  • If you post the Perl solution somewhere I'd be happy to help try and convert it :-) – Jon Cage Apr 28 '09 at 16:12
  • The Perl solution is really simple. I'm just taking advantage of the Mail::DKIM module, which makes signing an email pretty trivial. – Alex Fort Apr 28 '09 at 17:37
  • So something like this should make a Python implementation similarly trivial: http://hewgill.com/pydkim/ :-) – Jon Cage Apr 28 '09 at 22:23
  • ...ah, except it requires Python >= 2.5 ...rats! Out of curiosity, why are you still using 2.3 not a more recent build? – Jon Cage Apr 28 '09 at 22:29
  • I made some changes to pydkim so that it will operate in a degraded mode under Python 2.4, see the latest code on github: http://github.com/ghewgill/pydkim/tree/master (otherwise unreleased). It might be possible to also make it work under Python 2.3 but significantly more changes may be necessary. – Greg Hewgill Apr 29 '09 at 11:09
  • I'm just using 2.3 because that's what came installed on my RHEL 4 install. I'm not sure what could possibly break if I upgrade, so I've been putting that off, and since RHEL 4 repos contain 2.3, it'll probably have to compile from source to get something like 2.5 working. It's probably worth the trouble to get it upgraded, however. – Alex Fort Apr 29 '09 at 13:00
  • @Alex Fort: Most of my machines have two or more versions of Python installed. Generally, Python is pretty good about multiple versions coexisting, all the files go into /usr/local/lib/python2.x with the version as appropriate. Then the one binary goes into /usr/local/bin/python2.x, and /usr/local/bin/python is hardlinked to whatever version you want to be the default. You can then run "python test.py" for the default version or something "python2.4 test.py" for a specific version. – Greg Hewgill Apr 29 '09 at 20:09
1

I tried also to do that only configure how to make it work as

pipe = subprocess.Popen(
            ['someperlfile.perl', 'param(s)'],
            stdin=subprocess.PIPE
        )
response = pipe.communicate()[0]

I wish this will assist u to make it work.

fth
  • 2,478
  • 2
  • 30
  • 44