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

2024-05-15 14:54:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试构建一个函数,该函数将从项目根目录中删除所有以“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)

我一点运气都没有——它好像什么也没做。你知道我做错了什么吗?谢谢您!


Tags: 文件path项目函数projectcmdosargs
3条回答

您是否考虑使用os.remove()而不是rm删除文件的方法:

import os
os.remove('Path/To/filename.ext')

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

由于os.remove()无法单独处理通配符,因此使用glob模块来帮助您将得到一个解决方案,该解决方案将从此SO answer中逐字重复:

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

我想试试这样的东西(它也适用于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)

问题是,您将两个参数传递给subprocess.Popenrm和路径,例如/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)

(否则,the list of arguments will be given to the new shell, not to the command

另一种更安全、更高效的解决方案是使用the ^{} module

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

总之,不过,我同意列文解决方案是更明智的。在这种情况下,glob也是答案:

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

相关问题 更多 >