python subprocess.call() 在将参数传递给 shell-脚本之前修改参数?
python subprocess.call() modifies arguments before passing it to shell-script?
我正在编写一个 python 包装器来调用 AMOS 程序包的程序(特别是用于使用来自 AMOS 的 good ol' minimus2 合并来自不同来源的基因组组件)。
直接使用shell时,脚本应该这样调用:
toAmos -s myinput.fasta -o testoutput.afg
minimus2 testoutput -D REFCOUNT=400 -D OVERLAP=500
[just for clarification:
-toAmos: converts my input.fasta file to .afg format and requires an input sequence argument ("-s") and an output argument ("-o")
-minimus2: merges a sequence dataset against reference contigs and requires an argument "-D REFCOUNT=x" for stating the number of rerference seqeunces in your input and an argument "-D OVERLAP=Y" for stating the minimum overlap between sequences]
所以在我的脚本中,我使用 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
作为解决方法,但互联网上充满了明确建议不要这样做的说明。
这里似乎有什么问题?
我能做什么?
回答
要么:
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
之后没有 space),"-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'
),或删除 spaces ('-DREFCOUNT=400', '-DOVERLAP=500'
)。
附加信息
您似乎不了解 shell 如何拆分命令行;我建议您始终使用单字符串方法,除非文件名中有 space 或者您必须使用 shell=False
选项;在这种情况下,我建议您始终提供参数列表。
-s
和后面的输入文件名应该是 call
的单独参数,因为它们在命令行中:
call(["toAmos", "-s", inputfile, "-o", output_basename + ".afg"])
我正在编写一个 python 包装器来调用 AMOS 程序包的程序(特别是用于使用来自 AMOS 的 good ol' minimus2 合并来自不同来源的基因组组件)。
直接使用shell时,脚本应该这样调用:
toAmos -s myinput.fasta -o testoutput.afg
minimus2 testoutput -D REFCOUNT=400 -D OVERLAP=500
[just for clarification:
-toAmos: converts my input.fasta file to .afg format and requires an input sequence argument ("-s") and an output argument ("-o")
-minimus2: merges a sequence dataset against reference contigs and requires an argument "-D REFCOUNT=x" for stating the number of rerference seqeunces in your input and an argument "-D OVERLAP=Y" for stating the minimum overlap between sequences]
所以在我的脚本中,我使用 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
作为解决方法,但互联网上充满了明确建议不要这样做的说明。
这里似乎有什么问题? 我能做什么?
回答
要么:
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
之后没有 space),"-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'
),或删除 spaces ('-DREFCOUNT=400', '-DOVERLAP=500'
)。
附加信息
您似乎不了解 shell 如何拆分命令行;我建议您始终使用单字符串方法,除非文件名中有 space 或者您必须使用 shell=False
选项;在这种情况下,我建议您始终提供参数列表。
-s
和后面的输入文件名应该是 call
的单独参数,因为它们在命令行中:
call(["toAmos", "-s", inputfile, "-o", output_basename + ".afg"])