2011-12-13 58 views
0

我知道我做错了什么。Python subprocess.check_call问题

在壳我键入:

cuebreakpoints cuefile.cue | shnsplit -o flac flacfile.flac 

这将随后根据cuefile分裂后手文件。由于我正在编写一个小型的帮助工具(使用Python)来转换flac文件,所以我显然希望将这一位合并到我的代码中。

因此,在一个Python化的方式,我写道:

for root, dirs, files in os.walk(args): 
    ... 
    cmd = ('cuebreakpoints', cue, '|', 'shnsplit', '-o', 'flac', flacs[0]) 
    subprocess.check_call(cmd, cwd=None) 
    .... 

'提示' 是cuefile和 'FLACS [0]' 是后手文件。但我得到一个:

subprocess.CalledProcessError: Command '('cuebreakpoints', '41_30sec.cue', '|', 'shnsplit', '-o', 'flac', '41_30sec.flac')' returned non-zero exit status 1

由于PIPE有问题吗?

回答

2

作为将命令字符串传递给shell(并跳过larsmans指出的安全问题)的替代方法,您可以创建两个对象,并将第一个对象的输出连接到第二个输入(这是基本上外壳会为你做什么):

有关如何做到这一点的示例,请查看文档中的replacing shell pipeline部分。

+0

谢谢,我会用它。 –

2

如果你想使用shell功能,如管道,你需要给check_call一个shell=True kwarg并给命令作为一个字符串:

check_call("cuebreakpoints '%s' | shnsplit -o flac '%s'" % (cue, flacs[0]), 
      shell=True) 

但是请注意,shell=Truepotential security hazard与unsanitized使用时cueflacs

+0

谢谢,因为我想不使用shell = True我会去与jcollado的答案。当然,你们都是正确的,所以再次感谢 –

+0

@ wagner-felix:如果你放弃了答案中的''',那么'pipes.quote'应该足够用于文件名清理。虽然,jcollado +1。 –

0

这里有一个小小的注释。

使用子命令编写python脚本时,我发现shlex确实有助于解析更复杂的命令,而不必担心列表的外观。

import shlex 

... 
cmd = "cuebreakpoints '%s' | shnsplit -o flac '%s'" % (cue, flacs[0]) 
args = shlex.split(cmd) 

subprocess.call(args ...) 
+1

我认为这种情况在这种情况下不起作用,因为管道。 – jcollado