3

There are a variety of posts and resources explaining how to use Python to get output of an outside call. I am familiar with using these--I've used Python to get output of jars and exec several times, when it was not realistic or economical to re-implement the functionality of that jar/exec inside Python itself.

I am trying to call a Perl script via Python's subprocess module, but I have had no success with this particular Perl script. I carefully followed the answers here, Call Perl script from Python, but had no results.

I was able to get the output of this test Perl script from this question/answer: How to call a Perl script from Python, piping input to it?

#!/usr/bin/perl

use strict;
use warnings;

my $name = shift;

print "Hello $name!\n";

Using this block of Python code:

import subprocess

var = "world"

args_test = ['perl', 'perl/test.prl', var]

pipe = subprocess.Popen(args_test, stdout=subprocess.PIPE)

out, err = pipe.communicate()

print out, err

However, if I swap out the arguments and the Perl script with the one I need output from, I get no output at all.

args = ['perl', 'perl/my-script.prl', '-a', 'perl/file-a.txt',
         '-t', 'perl/file-t.txt', 'input.txt']

which runs correctly when entered on the command line, e.g.

>perl perl/my-script.prl -a perl/file-a.txt -t perl/file-t.txt input.txt

but this produces no output when called via subprocess:

pipe = subprocess.Popen(args, stdout=subprocess.PIPE)

out, err = pipe.communicate()

print out, err

I've done another sanity check as well. This correctly outputs the help message of Perl as a string:

import subprocess

pipe = subprocess.Popen(['perl', '-h'], stdout=subprocess.PIPE)

out, err = pipe.communicate()

print out, err

As shown here:

>>> ================================ RESTART ================================
>>>

Usage: perl [switches] [--] [programfile] [arguments]
  -0[octal]       specify record separator (\0, if no argument)
  -a              autosplit mode with -n or -p (splits $_ into @F)
  -C[number/list] enables the listed Unicode features
  -c              check syntax only (runs BEGIN and CHECK blocks)
  -d[:debugger]   run program under debugger
  -D[number/list] set debugging flags (argument is a bit mask or alphabets)
  -e program      one line of program (several -e's allowed, omit programfile)
  -f              don't do $sitelib/sitecustomize.pl at startup
  -F/pattern/     split() pattern for -a switch (//'s are optional)
  -i[extension]   edit <> files in place (makes backup if extension supplied)
  -Idirectory     specify @INC/#include directory (several -I's allowed)
  -l[octal]       enable line ending processing, specifies line terminator
  -[mM][-]module  execute "use/no module..." before executing program
  -n              assume "while (<>) { ... }" loop around program
  -p              assume loop like -n but print line also, like sed
  -P              run program through C preprocessor before compilation
  -s              enable rudimentary parsing for switches after programfile
  -S              look for programfile using PATH environment variable
  -t              enable tainting warnings
  -T              enable tainting checks
  -u              dump core after parsing program
  -U              allow unsafe operations
  -v              print version, subversion (includes VERY IMPORTANT perl info)
  -V[:variable]   print configuration summary (or a single Config.pm variable)
  -w              enable many useful warnings (RECOMMENDED)
  -W              enable all warnings
  -x[directory]   strip off text before #!perl line and perhaps cd to directory
  -X              disable all warnings

None
Community
  • 1
  • 1
user3898238
  • 957
  • 3
  • 11
  • 25
  • I wonder what you expect perl switches `-a` and `-t` to do? Neither of them take parameters, so your call is equivalent to something like `perl -at perl/my-script.prl perl/file-a.txt perl/file-t.txt input.txt`, which runs Perl program `my-script.prl` with three input files. – Borodin Jan 29 '15 at 21:18
  • 1
    Suffering from buffering? What if you close the pipe before you call `print out,err` ? – mob Jan 29 '15 at 21:32
  • Can you share a representative portion of your Perl script that will give us an idea of what it's doing? – rchang Jan 29 '15 at 21:33
  • @mob +1 for "Suffering from buffering"...I'm going to shamelessly steal that if you don't mind. =) – rchang Jan 29 '15 at 21:34
  • @mob How could the pipe get closed for `my-script.prl` but not for `test.prl`, if they are run in the exact same Python set up? I don't know Perl and the script is proprietary unfortunately. @Borodin I tried using `perl -at perl/my-script.prl perl/file-a.txt perl/file-t.txt input.txt`, which did not work with Python. – user3898238 Jan 29 '15 at 21:38
  • @rchang Google it. Everyone else just shamelessly steals it from Mark Jason Dominus., – mob Jan 29 '15 at 21:39
  • 3
    Swinging in the dark here, but is it at all possible the script is actually writing output to STDERR instead of STDOUT? You could add `stderr=subprocess.PIPE` to the `Popen` constructor to test that. – rchang Jan 29 '15 at 21:43
  • You might also want to call perl via it's full path, eg `/usr/bin/perl` of whatever path shows when you run `which perl` on your system. – elcaro Jan 29 '15 at 22:05
  • @rchang That helped me resolve the issue. I appended the relevant print statements with `STDERR` and was able to get the output. – user3898238 Jan 30 '15 at 16:26

0 Answers0