2016-11-25 89 views
-1

我目前正在编写一个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

难道是程序,你对当前的工作目录有不同的想法吗?为了测试这个假设,为'seq =“/ some/dir/acgtgagtag”'使用绝对文件名。并且请注意,在错误消息中,该文件具有“.in”后缀...不在seq中。 – Jens

+0

终端上的'./DNAanalyzer acgtgagtag'是否给出同样的错误?这与运行'.DNAanalyzer'然后输入'acgtgagtag'不同。这听起来像程序期望一个文件名,而你给它一个字符串。 –

+0

@thatotherguy ./DNAanalyzer不会给出与终端相同的错误,因为它会自动提供允许手动输入输入的选项。在任何情况下,可执行文件的手册都说明文件必须在命令行为一个字符串。 –

回答

1

Popen()实际上是一个对象的构造函数 - 该对象是直接运行可执行文件的“子外壳”。但是因为我没有设置标准输入或输出(stdinstdout),所以它们默认为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()格式化的输入字符串。现在可以读取输出,并在脚本中以任何方式进一步处理。