Python 使用shlex的子进程调用中的通配符不起作用

Python 使用shlex的子进程调用中的通配符不起作用,python,subprocess,shlex,Python,Subprocess,Shlex,语言:Python v2.6.2 操作系统:AIX5.3 我正在使用Python将一些文件从备份恢复到测试系统-所有命令都以下面的方式调用,但是有些命令根本不想工作 #!/usr/bin/python import subprocess, shlex cmd = 'sudo rm -rf /work/TEST/*' arg = shlex.split(cmd) # This does not work p = subprocess.Popen(arg) # This, however, w

语言:Python v2.6.2

操作系统:AIX5.3

我正在使用Python将一些文件从备份恢复到测试系统-所有命令都以下面的方式调用,但是有些命令根本不想工作

#!/usr/bin/python
import subprocess, shlex

cmd = 'sudo rm -rf /work/TEST/*'
arg = shlex.split(cmd)

# This does not work
p = subprocess.Popen(arg)

# This, however, works just fine
p = subprocess.Popen(cmd, shell=True)
如果我从命令中删除*,它们就可以很好地工作(好吧,它们在没有通配符的情况下可以正常工作,不幸的是,这不是我想要的)

出于明显的安全原因,我真的不想使用shell=True,但是有几个其他命令基本上可以做同样的事情。如果命令中有一个通配符,它就不会工作——它执行时不会出错,只是什么也不做

有趣的是,下面的命令(通过shlex解析):

产生以下结果:

mv:0653-401无法将/work/testrestore/production/*重命名为/work/TESTC/*:路径名中的文件或目录不存在

这就好像unix现在正在尝试移动名为*的文件,而不是使用*作为通配符。这是shlex的典型行为吗


编辑:我尝试过用\来转义*,也尝试过将单引号改为双引号。。并不是我期望它能做任何事情。

要用它的意思替换
*
,您要么需要shell,要么需要
glob
模块。因此最简单的方法是
shell=True
(如果命令是常量,我看不到任何安全漏洞)

另一种方法是

#!/usr/bin/python
import subprocess
import shlex
import glob

cmd = 'sudo rm -rf /work/TEST/*'
arg = shlex.split(cmd)
arg = arg[:-1] + glob.glob(arg[-1])

# This should work now
p = subprocess.Popen(arg)
或者,如果您仍然要自己附加路径

cmd = 'sudo rm -rf'
basearg = shlex.split(cmd)
arg = basearg + glob.glob(path+"/*")

谢谢,这似乎已经解决了这个问题-我使用了glob,因为我的一些调用包含用户输入(在我发现偏执狂是一件好事之前,我会先检查用户输入)。你知道这样做的原因吗?我认为这与子进程在直接将命令传递给shell时如何处理命令有关,但令我感到奇怪的是,它无法处理通配符。不,这只是因为
*
有一个特殊的含义,必须应用它才能生效。通常,此扩展由外壳执行。因为我们这里不使用它们,所以我们必须用另一种方法
glob
是最简单的方法;您还可以手动提供给定目录中的文件列表
cmd = 'sudo rm -rf'
basearg = shlex.split(cmd)
arg = basearg + glob.glob(path+"/*")