我目前正在编写一个Python脚本,它将一些RNA序列(字符串)传输到UNIX可执行文件中,在处理完它们之后,它会将输出发送回我的Python脚本以供进一步处理。我正在使用子进程模块执行此操作。
但是,为了运行可执行文件,它还必须提供一些额外的参数。使用subprocess.call方法,我一直在尝试运行:
import subprocess
seq= "acgtgagtag"
output= subprocess.Popen(["./DNAanalyzer", seq])
尽管我的环境变量设置正确,但是从终端的命令行运行没有问题的可执行文件,以及正常运行的子进程模块(例如subprocess.Popen([“ls”])工作正常),Unix可执行文件打印出相同的输出:
Failed to open input file acgtgagtag.in
Requesting input manually.
这个包中还有一些其他的Unix可执行文件,它们的行为方式相同。我甚至尝试创建一个包含序列的简单文本文件,并在Python脚本和命令行中将其指定为输入,但可执行文件只需要手动输入。
我查看了软件包的手册,但没有提到为什么可执行文件表面上只能通过命令行运行。因为我对这个模块(以及一般的Python)的经验有限,任何人都可以指出这个问题的最佳方法是什么?
答案 0 :(得分:1)
Popen()
实际上是一个对象的构造函数 - 该对象是一个"子shell"直接运行可执行文件。但由于我没有设置标准输入或输出(stdin
和stdout
),因此默认为None
,这意味着进程的I / O都是闭合。
我应该做的是传递subprocess.PIPE
以表示我想要在我的程序和进程之间管道输入和输出的Popen
对象。
此外,脚本的环境变量(在主shell中)与子shell的环境变量不同,并且这些特定的可执行文件需要某些环境变量才能运行(在这种情况下,它是路径到其包中的参数文件)。这是以下列方式完成的:
import subprocess as sb
seq= "acgtgagtag"
my_env= {BIOPACKAGEPATH: "/Users/Bobmcbobson/Documents/Biopackage/"}
p= sb.Popen(['biopackage/bin/DNAanalyzer'], stdin=sb.PIPE, stdout=sb.PIPE, env=my_env)
strb = (seq + '\n').encode('utf-8')
data = p.communicate(input=strb)
创建Popen
对象后,我们使用communicate()
向其发送格式化的输入字符串。现在可以读取输出,并以任何方式在脚本中进一步处理。