1

I have a python script which must call a perl script to get data from a remote server. The perl script has to stay perl, it's third party and I don't have any options there. I'm trying to remove all the obsolete and deprecated stuff that the previous developer stuck all around the code, so I'd like to replace the commands.getstatusoutput call with a subprocess call, but somehow I can't seem to get it to work...

Up until now, the script was called via commands.getstatusoutput(string) where string is the full system call to the perl script, as in '/usr/bin/perl /path/to/my/perl/script.pl < /path/to/my/input'.

I create a list of arguments (args = ['/usr/bin/perl', '/path/to/my/perl/script.pl', '<', '/path/to/my/input']) and I pass it to subprocess.call:

args = ['/usr/bin/perl', '/path/to/my/perl/script.pl', '<', '/path/to/my/input']
strOut = subprocess.call(args)
print strOut

Unfortunately, this fails with the error :

port absent at /path/to/my/perl/script.pl line 9.

The perl script is :

#!/usr/bin/perl
use IO::Handle;
use strict;
use Socket;
my ($remote, $port, $iaddr, $paddr, $proto, $ligne);
$remote = shift || 'my.provider.com';
$port   = shift || 9000;
if ($port =~ /\D/) { $port = getservbyname ($port, 'tcp'); }
die "port absent" unless $port;

Despite reading other similar threads here (Call perl script from python, How to call a perl script from python?, How can I get the results of a Perl script in Python script?, Python getstatusoutput replacement not returning full output etc) and elsewhere, I get the feeling I am missing something obvious but I can't work out what.

Any ideas?

Thanks.

Community
  • 1
  • 1
Oliver Henriot
  • 181
  • 1
  • 10

1 Answers1

2

redirection < is a shell feature. If you want to use it, you'll need to pass a string to subprocess.call and use shell = True. e.g.:

args = ['/usr/bin/perl', '/path/to/my/perl/script.pl', '<', '/path/to/my/input']
strOut = subprocess.call(' '.join(args), shell = True)

Alternatively, you can do:

args = ['/usr/bin/perl', '/path/to/my/perl/script.pl']
with open('path/to/my/input') as input_file:
    strOut = subprocess.call(args, stdin = input_file) 

Finally, strOut will hold the return code from your perl program -- this seems like a funny name for it. If you want to get at the output stream (stdout) from your perl program, you'll probably want to use subprocess.Popen in conjunction with stdout=subprocess.PIPE and communicate.

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • My most heartfelt thanks for your detailed answer, it really helped me out. That's exactly what I was missing. And yes, I need subprocess.PIPE and communicate to get the data I want as you very rightly point out. – Oliver Henriot Sep 24 '12 at 09:21