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

myt*_*889 15 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)
    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)
Run Code Online (Sandbox Code Playgroud)

我没有运气 - 它似乎没有做任何事情.你有什么想法我可能做错了吗?谢谢!

Lev*_*von 15

你会考虑使用os.remove()来删除文件而不是rm:

import os
os.remove('Path/To/filename.ext')
Run Code Online (Sandbox Code Playgroud)

更新(基本上将我的评论从下面移到我的答案中):

由于os.remove()无法自行处理通配符,因此使用glob模块帮助将从这个SO答案中逐字逐句地产生解决方案:

import glob
import os
for fl in glob.glob("E:\\test\\*.txt"):
    #Do what you want with the file
    os.remove(fl)
Run Code Online (Sandbox Code Playgroud)

  • `os.remove()` 本身不能处理通配符,但是这个 SO 答案显示了一些使用 `os.remove()` 和 `glob` 模块来做到这一点的代码:http://stackoverflow.com/a /5532521/1209279 .. 还显示了其他方法。 (2认同)

bra*_*zzi 14

问题是你将两个参数传递给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)
Run Code Online (Sandbox Code Playgroud)

(否则,参数列表将被赋予新shell,而不是命令)

另一个更安全,更高效的解决方案是使用glob模块:

import glob
files = glob.glob(prepend+"*")
args = [cmd] + files
Popen(args,  stdin=PIPE, stdout=PIPE, stderr=PIPE)
Run Code Online (Sandbox Code Playgroud)

总而言之,我同意levon解决方案更为理智.在这种情况下,glob答案也是:

files = glob.glob(prepend+"*")
for file in files:
    os.remove(file)
Run Code Online (Sandbox Code Playgroud)