在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
保留为列表,而不是将其作为字符串
我怎样才能做到这一点?
答案 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()
...