我正在编写一个使用一些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'])
答案 0 :(得分:2)
据我所知,你有三个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?
的响应可能包含可能危及您系统的恶意shell代码。但是如果使用你的程序的人可以像他们选择的那样直接破坏你的系统,那么什么都不会丢失
另一个问题是对中间文件使用固定名称。
无法保证单独的独立进程不会使用具有相同路径的文件,因此理论上该过程是不安全的。
我跟随您的主导并使用result
作为run_esearch.pl
的输出,并为shrink1_out
的输出发明shrink.pl
,但正确的程序将使用tempfile
模块并调用tempfile.NamedTemporaryFile
来创建保证唯一的中间文件
答案 1 :(得分:1)
我会用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)
答案 2 :(得分:0)
以下是如何使用bash
将输出重定向到文件test.txt
的示例:
import subprocess
#STAGE 2----------------------------------------------------------------------
subprocess.Popen(['bash', '-c', 'echo Hello > test.txt'])
#STAGE 3----------------------------------------------------------------------
subprocess.Popen(['perl', '-nE', 'say $_', 'test.txt'])