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.

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.