我知道我做错了什么。
在shell中我会输入:
cuebreakpoints cuefile.cue | shnsplit -o flac flacfile.flac
然后根据cuefile分割flac文件。由于我正在编写一个小的帮助工具(在Python中)来转换flac文件,我显然希望将这一点合并到我的代码中。
所以我用pythonic的方式写道:
for root, dirs, files in os.walk(args):
...
cmd = ('cuebreakpoints', cue, '|', 'shnsplit', '-o', 'flac', flacs[0])
subprocess.check_call(cmd, cwd=None)
....
'cue'是cuefile,'flacs [0]'是flac文件。但是我得到了:
subprocess.CalledProcessError:命令'('cuebreakpoints','41_30sec.cue','|','shnsplit',' - o','flac','41_30sec.flac')'返回非零退出状态1
因为PIPE有问题吗?
答案 0 :(得分:2)
如果你想使用管道等shell功能,你需要给check_call
一个shell=True
kwarg并将命令作为单个字符串提供:
check_call("cuebreakpoints '%s' | shnsplit -o flac '%s'" % (cue, flacs[0]),
shell=True)
但请注意,shell=True
与未经审核的cue
或flacs
一起使用时为potential security hazard。
答案 1 :(得分:2)
作为将命令字符串传递给shell(并跳过larsmans指出的安全问题)的替代方法,您可以创建两个subprocess.Popen
对象并将第一个的输出连接到第二个的输入一个(这基本上就是shell会为你做的):
有关如何执行此操作的示例,请查看文档中的replacing shell pipeline部分。
答案 2 :(得分:0)
这里有一点注意事项。
使用子命令编写python脚本时,我发现shlex对于解析更复杂的命令非常有帮助,而不必过多担心列表的外观。
import shlex
...
cmd = "cuebreakpoints '%s' | shnsplit -o flac '%s'" % (cue, flacs[0])
args = shlex.split(cmd)
subprocess.call(args ...)