如何在不使用shell = True的情况下执行此Python子进程调用?

时间:2014-05-07 00:07:29

标签: python bash subprocess

例如,在/ tmp中我有以.txt,.doc和.jpg结尾的文件,我想使用shred和subprocess一步删除。

以下工作:

subprocess.call('bash -c "shred -n 5 -uz /tmp/{*.txt,*.pdf,*.doc}"', shell=True)

如果不使用shell = True,我将如何执行此命令。我尝试了以下内容:

subprocess.call(['bash', '-c', '"shred -n 10 -uz /tmp/{*.txt,*.pdf,*.doc}"'])
subprocess.call(['bash', '-c', 'shred', '-n 10', '-uz', '/tmp/{*.txt,*.pdf,*.doc}'])

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

我相信其他人是现货(尽管我自己也没试过)。但是,如果您再次发现自己遇到类似问题shlex.split(s)可能会有所帮助。它需要字符串'并使用类似shell的语法"来分割它"

In [3]: shlex.split(s)
Out[3]: ['bash', '-c', 'shred -n 5 -uz /tmp/{*.txt,*.pdf,*.doc}']

答案 1 :(得分:1)

subprocess.call(['bash', '-c', 'shred -n 10 -uz /tmp/{*.txt,*.pdf,*.doc}'])

您可以通过以下方式告诉如何扩展和拆分命令:

$ printf "Argument: %s\n" bash -c "shred -n 5 -uz /tmp/{*.txt,*.pdf,*.doc}"
Argument: bash
Argument: -c
Argument: shred -n 5 -uz /tmp/{*.txt,*.pdf,*.doc}

在更一般的情况下(但在这里过度杀戮),如果您对使用哪些参数执行的操作有疑问,可以使用strace:

$ cat script
import subprocess
subprocess.call('bash -c "shred -n 5 -uz /tmp/{*.txt,*.pdf,*.doc}"', shell=True)

$ strace -s 1000 -fe execve python script
...
execve("/bin/bash", ["bash", "-c", "shred -n 5 -uz /tmp/{*.txt,*.pdf,*.doc}"], [/* 49 vars */]) = 0
...
$ 

答案 2 :(得分:1)

如果命令来自受信任的来源,例如,它是硬编码的,则使用shell=True没有任何问题:

#!/usr/bin/env python
from subprocess import check_call

check_call("shred -n 10 -uz /tmp/{*.txt,*.pdf,*.doc}",
           shell=True, executable='/bin/bash')

/bin/bash用于支持命令中的{}

此命令不会运行/bin/sh