通配符不使用shlex在子进程调用中工作

Spa*_*arc 5 python subprocess shlex

语言:Python v2.6.2

操作系统:AIX 5.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)
Run Code Online (Sandbox Code Playgroud)

如果我从命令中删除*,它们可以正常工作(好吧,它们可以在没有通配符的情况下工作,这是不幸的不是我想要的).

出于明显的安全原因,我真的不想使用shell = True,但是有一些其他命令基本上做同样的事情.如果命令中有通配符,它​​将无法正常工作 - 它会毫无错误地执行,只是不执行任何操作.

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

sudo mv /work/testrestore/production/* /work/TESTC
Run Code Online (Sandbox Code Playgroud)

产生以下内容:

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

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

编辑:我已经尝试用\来转义*,也尝试从单引号转换为双..不是我期望做任何事情.

glg*_*lgl 5

要替换*它意味着什么,你需要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)
Run Code Online (Sandbox Code Playgroud)

或者,如果你仍然自己追加路径,

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