问题
I'm trying to build a function that will remove all the files that start with 'prepend' from the root of my project. Here's what I have so far
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)
I'm not having any luck -- it doesn't seem to be doing anything. Do you have any ideas what I might be doing wrong? Thank you!
回答1:
The problem is that you are passing two arguments to subprocess.Popen
: rm
and a path, such as /home/user/t*
(if prefix is t
). Popen
then will try to remove a file named exactly this way: t followed by an asterisk at the end.
If you want to use Popen
with the wildcard, you should pass the shell
parameter as True
. In this case, however, the command should be a string, not a list of arguments:
Popen("%s %s" % (cmd, args), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(Otherwise, the list of arguments will be given to the new shell, not to the command)
Another solution, safer and more efficient, is to use the glob module:
import glob
files = glob.glob(prepend+"*")
args = [cmd] + files
Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
All in all, however, I agree that levon solution is the saner one. In this case, glob
is the answer too:
files = glob.glob(prepend+"*")
for file in files:
os.remove(file)
回答2:
Would you consider this approach using os.remove() to deleting files instead of rm
:
import os
os.remove('Path/To/filename.ext')
Update (basically moving my comment from below into my answer):
As os.remove()
can't handle wildcards on its own, using the glob module to help will yield a solution as repeated verbatim from this SO answer:
import glob
import os
for fl in glob.glob("E:\\test\\*.txt"):
#Do what you want with the file
os.remove(fl)
回答3:
I would try something like this (which also works on Windows, though I'm guessing that's not a concern for you:
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)
来源:https://stackoverflow.com/questions/11025784/calling-rm-from-subprocess-using-wildcards-does-not-remove-the-files