Python 使用通配符从子流程调用rm不会删除文件

Python 使用通配符从子流程调用rm不会删除文件,python,django,shell,rm,Python,Django,Shell,Rm,我正在尝试构建一个函数,该函数将从我的项目根目录中删除所有以“prepend”开头的文件。这是我到目前为止所拥有的 def cleanup(prepend): prepend = str(prepend) PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) end = "%s*" % prepend cmd = 'rm' args = "%s/%s" % (PROJECT_ROOT, end)

我正在尝试构建一个函数,该函数将从我的项目根目录中删除所有以“prepend”开头的文件。这是我到目前为止所拥有的

def cleanup(prepend):
    prepend = str(prepend)
    PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
    end = "%s*" % prepend
    cmd = 'rm'
    args = "%s/%s" % (PROJECT_ROOT, end)
    print "full cmd = %s %s" %(cmd, args)
    try:
        p = Popen([cmd, args],  stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True).communicate()[0]
        print "p", p
    except Exception as e:
        print str(e)

我一点运气都没有,它好像什么也没做。你知道我可能做错了什么吗?谢谢大家!

> P>你会考虑使用这种方法来删除文件而不是代码> RM< /代码>:

import os
os.remove('Path/To/filename.ext')
更新(基本上将我的评论从下面移到我的答案中)

由于
os.remove()


问题是您正在将两个参数传递给
subprocess.Popen
rm
和一个路径,例如
/home/user/t*
(如果前缀是
t
Popen
然后将尝试删除一个名为:t的文件,并在末尾加上一个星号

如果要将
Popen
与通配符一起使用,则应将
shell
参数作为
True
传递。但是,在这种情况下,命令应该是字符串,而不是参数列表:

Popen("%s %s" % (cmd, args), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(否则,)

另一种更安全、更高效的解决方案是使用:

然而,总而言之,我同意levon解决方案是更明智的。在这种情况下,
glob
也是答案:

files = glob.glob(prepend+"*")
for file in files:
    os.remove(file)

我会尝试类似的方法(这也适用于Windows,但我猜这不是您关心的问题:

def cleanup(prepend):
    prepend = str(prepend)
    PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
    for file_to_delete in [file for file in os.listdir(PROJECT_ROOT) if file.startswith(prepend)]:
        os.remove(file_to_delete)

我认为Levon的答案是更好的方法;也就是说,如果你想知道它在做什么,在
strace(1)
下使用
-f
命令行选项运行它,你可以看到正在进行的确切的
execve(2)
系统调用。当然!我可以在remove调用中使用通配符吗?
os.remove()
本身无法处理通配符,但这个答案显示了一些代码使用
os.remove()
glob
模块来实现这一点:……还显示了其他方法。@mythander889否--通配符由shell进行评估,以及实现这一点的最佳方法(从安全角度看)没有涉及shell。
import glob,os;对于glob.glob('*.txt')中的文件名:os.remove(filename)
files = glob.glob(prepend+"*")
for file in files:
    os.remove(file)
def cleanup(prepend):
    prepend = str(prepend)
    PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
    for file_to_delete in [file for file in os.listdir(PROJECT_ROOT) if file.startswith(prepend)]:
        os.remove(file_to_delete)