繁体   English   中英

构建运行Perl脚本的Python脚本。 如何重定向stdout?

[英]Building a Python script which runs Perl scripts. How to redirect stdout?

我正在编写一个使用一些Perl脚本的Python脚本,但其中一个使用stdout,所以我必须在bash中使用重定向>将此输出写入文件。

所有输入和输出文件都是文本文件。

# -*- coding: utf-8 -*-
import subprocess 

filename = input("What the name of the input? ")

#STAGE 1----------------------------------------------------------------------
subprocess.Popen(["perl", "run_esearch.pl", filename , 'result'])

#STAGE 2----------------------------------------------------------------------
subprocess.Popen(["perl", "shrink.pl", 'result']) 
'''Here the input from stage one is "shrunk" to smaller file, but
the output is printed to the console. Is it possible to write this out
to a file in Python, so I can use it in stage 3? '''

#STAGE 3----------------------------------------------------------------------
subprocess.Popen(["perl", "shrink2.pl", 'stdoutfromstage2'])

据我所知,你有三个Perl程序

  • run_esearch.pl ,它需要两个命令行参数:输入文件的名称和输出文件的名称

  • shrink.pl ,它需要一个命令行参数:输入文件的名称。 它将其输出写入stdout

  • shrink2.pl ,它需要一个命令行参数:输入文件的名称。 你没有说它的输出

编写Linux程序的标准和最灵活的方法是从stdin读取它们并写入stdout 这样,可以使用<>重定向在命令行上显式指定输入和输出文件,或者可以使用相同的程序来读取和写入管道| 作为连锁店的一部分。 Perl程序拥有两全其美的优势。 使用空<>读取输入将从作为命令行参数提到的文件中收集所有数据,或者如果没有参数则从stdin读取

我无法知道缩小程序对输入的处理方式,所以我必须想象最坏的情况:它们显式打开并读取命令行上第一个参数指定的文件

Python的subprocess模块提供了Popen构造函数以及一些便利函数。 通常不需要使用构造函数,特别是如果您违反大多数参数并丢弃返回的对象,就像您一样

由于您将Python视为一个非常高级的shell,我建议您将shell命令字符串传递给subprocess.call ,并将shell参数设置为True 这将允许您提供bash命令字符串,您将更熟悉,因此感觉更有控制力

import subprocess 

filename = input("What's the name of the input? ")

subprocess.call("perl run_esearch.pl %s result" % filename, shell=True)

subprocess.call("perl shrink.pl result > shrink1_out", shell=True)

subprocess.call("perl shrink2.pl shrink1_out", shell=True)

请注意,此方法在生产代码中使用风险太大,因为What the name of the input?的响应是What the name of the input? 可能包含可能危及您的系统的恶意shell代码。 但是如果使用你的程序的人可以像他们选择的那样直接破坏你的系统,那么什么都不会丢失

另一个问题是为中间文件使用固定名称。 无法保证单独的独立进程不会使用具有相同路径的文件,因此理论上该过程是不安全的。 我跟踪你的导致并使用result输出run_esearch.pl ,并为shrink1_out的输出发明了shrink.pl ,但正确的程序将使用tempfile模块并调用tempfile.NamedTemporaryFile来创建保证唯一的中间文件

我会在Python中处理该文件:

link = "stage2output"
subprocess.call(["perl", "run_esearch.pl", filename, "result"])
with open(link, "w") as f:
    subprocess.call(["perl", "shrink.pl", "result"], stdout=f)
subprocess.call(["perl", "shrink2.pl", link])

如果shrink2.pl可以采用文件名-从标准输入读取:

subprocess.call(["perl", "run_esearch.pl", filename, "result"])
p2 = subprocess.Popen(["perl", "shrink.pl", "result"], stdout=subprocess.PIPE)
subprocess.call(["perl", "shrink2.pl", "-"], stdin=p2.stdin)

以下是如何使用bash将输出重定向到文件test.txt的示例:

import subprocess 

#STAGE 2----------------------------------------------------------------------
subprocess.Popen(['bash', '-c', 'echo Hello > test.txt']) 

#STAGE 3----------------------------------------------------------------------
subprocess.Popen(['perl', '-nE', 'say $_', 'test.txt'])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM