python subprocess.call()在将参数传递给shell脚本之前修改参数?

时间:2017-06-07 09:24:11

标签: python bash shell subprocess amos

我正在编写一个用于调用AMOS包程序的python包装器(专门用于使用来自AMOS的良好ol' minimus2来合并来自不同来源的基因组组件)。

直接使用shell时,应该像这样调用脚本:

toAmos -s myinput.fasta -o testoutput.afg
minimus2 testoutput -D REFCOUNT=400 -D OVERLAP=500
  

[仅用于澄清:

     

-toAmos:将我的input.fasta文件转换为.afg格式,并需要输入序列参数(" -s")和输出参数(" -o" )

     

-minimus2:将序列数据集与参考contigs合并,并需要一个参数" -D REFCOUNT = x"用于说明输入中的重新参考序列的数量和参数" -D OVERLAP = Y"用于说明序列之间的最小重叠]

因此,在我的脚本中,我使用subprocess.call()来调用必要的AMOS工具。

基本上我这样做:

from subprocess import call:
output_basename = "testoutput"
inputfile = "myinput.fasta"

call(["toAmos", "-s " + inputfile, "-o " + output_basename + ".afg"])
call(["minimus2", output_basename, "-D REFCOUNT=400", "-D OVERLAP=500"])

但在这种情况下,AMOS工具不再能解释参数。参数似乎被subprocess.call()修改并且传递不正确。我得到的错误信息是:

Unknown option: s myinput.fasta
Unknown option: o testoutput.afg
You must specify an output AMOS AFG file with option -o
/home/jov14/tools/miniconda2/bin/runAmos: unrecognized option '-D REFCOUNT=400'
Command line parsing failed, use -h option for usage info

似乎没有领先的" - "?所以我尝试将命令作为单个字符串(包括参数)传递,如下所示:

call(["toAmos -s " + inputfile +" -o " + output_basename + ".afg"])

但后来我收到了这个错误...

OSError: [Errno 2] No such file or directory

...大概是因为subprocess.call将整个字符串解释为单个脚本的名称。 我想我可能会尝试shell=True作为一种解决方法,但互联网上有完整的说明,明确建议不要这样做。

这里似乎有什么问题? 我该怎么办?

2 个答案:

答案 0 :(得分:2)

答案

要么:

call("toAmos -s " + inputfile +" -o " + output_basename + ".afg") # single string

或做:

call(["toAmos", "-s", inputfile, "-o", output_basename + ".afg"]) # list of arguments

讨论

如果您:

call(["toAmos", "-s " + inputfile, "-o " + output_basename + ".afg"])

你应该提供:

  • "-s" + inputfile-s之后没有空格),"-o" + output_basename + ".afg"
  • "-s", inputfile(单独的参数),"-o", output_basename + ".afg"

如果您:

call(["minimus2", output_basename, "-D REFCOUNT=400", "-D OVERLAP=500"])

"-D REFCOUNT=400""-D OVERLAP=500"应分别作为两个项目提供('-D', 'REFCOUNT=400', '-D', 'OVERLAP=500'),或删除空格('-DREFCOUNT=400', '-DOVERLAP=500')。

其他信息

您似乎缺乏shell如何拆分命令行的知识;我建议你总是使用单字符串方法,除非文件名中有空格或者你必须使用shell=False选项;在这种情况下,我建议你总是提供一个参数列表。

答案 1 :(得分:1)

- (NSString *)stringToFormat:(NSString *)str { while (str.length <12) { str = [NSString stringWithFormat:@"%@0", str]; } return str; } 以下输入文件名应该是-s的单独参数,因为它们位于命令行中:

call