Popen用命令序列链接

时间:2016-07-05 14:40:47

标签: python python-3.x

在Windows上我成功运行了这个:

cmd = ["gfortran", "test.f90", "-o", "test.exe", "&&", "test.exe"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
print(p.stdout.read())

在Ubuntu上,我将cmd更改为:

cmd = ["gfortran", "test.f90", "-o", "test", "&&", "./test"]

并获得:

  

gfortran:致命错误:没有输入文件
  编译终止。

我希望将cmd保留为列表,而不是将其作为字符串 我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:2)

这是不可能的。当cmd是列表时,当shell为True时,它具有不同的含义。 Quoting docs

  

如果args是序列,则第一项指定命令字符串,   任何其他项目将被视为附加参数   外壳本身。

在将' '.join(shlex.quote(arg) for arg in cmd)的参数列表与pipes.quote一起传递给预期行为时,请使用Popen(在Python2中为shell=True。原始列表不会被变异,字符串将在传递给函数之前构建,并且一旦可能就收集垃圾。

答案 1 :(得分:1)

这就是文档所说的内容:

  

在POSIX上,shell = True,shell默认为/ bin / sh。如果args是   string,string指定通过shell执行的命令。   这意味着字符串必须完全按照原样进行格式化   在shell提示符下键入时。这包括,例如,引用或   反斜杠转义文件名,其中包含空格。如果args是   sequence,第一项指定命令字符串,以及任何   其他项目将被视为shell的附加参数   本身。

如果您想将参数保留为列表,可以在调用Popen时加入它们:

p = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, shell=True)

答案 2 :(得分:0)

您似乎正在使用shell=True允许您在命令行上执行&&。如果您已经使用subprocess,则不一定非必要:

cmd1 = ["gfortran", "test.f90", "-o", "test.exe"]
cmd2 = ["test.exe"]
if not subprocess.call(cmd1):
    p = subprocess.Popen(cmd2, ...)
    out, err = p.communicate()
    ...