0

I'm trying to execute a perl script within another python script. My code is as below:

command = "/path/to/perl/script/" + "script.pl"
input = "< " + "/path/to/file1/" + sys.argv[1] + " >"
output = "/path/to/file2/" + sys.argv[1]

subprocess.Popen(["perl", command, "/path/to/file1/", input, output])

When execute the python script, it returned:

No info key.

All path leading to the perl script as well as files are correct.

My perl script is executed with command:

perl script.pl /path/to/file1/ < input > output

Any advice on this is much appreciate.

Le Thanh Viet
  • 47
  • 2
  • 12
  • try the following approach as in this SO https://stackoverflow.com/questions/25079140/python-subprocess-popen-check-for-success-and-errors – David Michael Gang Jun 25 '15 at 07:33
  • What do you mean, nothing happened? As far as the output is concerned, you `communicate` with the process, but you don't print or otherwise do anything with the communication result (process's stdout) in your Python script. As per [the documentation](https://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate): "communicate() *returns* a tuple (stdoutdata, stderrdata)." (emphasis mine.) –  Jun 25 '15 at 07:34
  • 3
    You're using the shell redirect operators as part of your input string. Thus, subprocess will try and run something like `perl /path/to/perl/script/script.pl '< /path/to/file1/arg1 >' /path/to/file2/`. That is, the `<`, and `>` become part of the input filename. –  Jun 25 '15 at 07:37
  • @Evert thanks so much! I got it working. Yes its shell redirect, i replace it with stdin and stdout, its working as it should now. – Le Thanh Viet Jun 25 '15 at 08:30

1 Answers1

2

The analog of the shell command:

#!/usr/bin/env python
from subprocess import check_call

check_call("perl script.pl /path/to/file1/ < input > output", shell=True)

is:

#!/usr/bin/env python
from subprocess import check_call

with open('input', 'rb', 0) as input_file, \
     open('output', 'wb', 0) as output_file:
    check_call(["perl", "script.pl", "/path/to/file1/"],
               stdin=input_file, stdout=output_file)

To avoid the verbose code, you could use plumbum to emulate a shell pipeline:

#!/usr/bin/env python
from plumbum.cmd import perl $ pip install plumbum

((perl["script.pl", "/path/to/file1"] < "input") > "output")()

Note: Only the code example with shell=True runs the shell. The 2nd and 3rd examples do not use shell.

jfs
  • 399,953
  • 195
  • 994
  • 1,670