2016-07-16 3 views
0

Итак, мне нужно очистить каталог, который не пуст. Я создал следующие причины тестирования function.For Я пытался удалить установку JDKУдалить каталог, который не пуст на python

def clean_dir(location): 
    fileList = os.listdir(location) 

    for fileName in fileList: 
     fullpath=os.path.join(location, fileName) 
     if os.path.isfile(fullpath): 
      os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) 
      os.remove(location + "/" + fileName) 
     elif os.path.isdir(fullpath): 
      if len(os.listdir(fullpath)) > 0: 
       clean_dir(fullpath) 
      #os.rmdir(location + "/" + fileName) 
      shutil.rmtree(location + "/" + fileName) 

    return 

Я пытался использовать rmtree и RmDir, но терпит неудачу.

ошибка я получил с помощью rmtree является:

OSError: Cannot call rmtree on a symbolic link

И это ошибка я получил, когда я использовал RmDir:

OSError: [Errno 66] Directory not empty: '/tmp/jdk1.8.0_25/jre/lib/amd64/server'

Код правильно работает на окнах. Но по какой-то причине он терпит неудачу в Linux.

+0

Вы направляете rmtree по символической ссылке, а не каталог. https://en.wikipedia.org/wiki/Symbolic_link – iScrE4m

+0

Если это символическая ссылка, я думаю, что 'os.unlink (...)' - это все, что вам нужно. (Чтобы уточнить, это просто удалит символическую ссылку. Он не удалит ничего, на что указывает символическая ссылка.) – smarx

+0

IIRC, 'os.unlink' также должен удалять файлы. – kronenpj

ответ

1

kronenpj спасибо, это была идея. Но когда у вас есть симлинк, он пытается удалить файл как обычный файл и не работает. Я должен был добавить новый Элиф и добавьте UNLINK вариант для линке

 
def clean_dir(location): 
    fileList = os.listdir(location)

for fileName in fileList: fullpath=os.path.join(location, fileName) if os.path.isfile(fullpath): os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) os.remove(os.path.join(location, fileName)) elif os.path.islink(fullpath): os.unlink(fullpath) elif os.path.isdir(fullpath): if len(os.listdir(fullpath)) > 0: clean_dir(fullpath) #os.rmdir(location + "/" + fileName) shutil.rmtree(os.path.join(location, fileName)) return

+0

Абсолютно корректно, я не был уверен, будет ли 'remove()' корректно обрабатывать символические ссылки или нет. – kronenpj

2

Вы сталкиваетесь с одним из различий между тем, как Windows и Linux (UNIX действительно) обрабатывают файловые системы. Я считаю, добавив еще один случай к коду, по крайней мере помощи:

... 
for fileName in fileList: 
    fullpath = os.path.join(location, fileName) 
    ## |<-- Handle symlink -->| 
    if os.path.islink(fullpath) or os.path.isfile(fullpath): 
     os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) 
     os.remove(os.path.join(location, fileName)) 
    elif os.path.isdir(fullpath): 
     if len(os.listdir(fullpath)) > 0: 
      clean_dir(fullpath) 
     #os.rmdir(os.path.join(location, fileName)) 
     shutil.rmtree(os.path.join(location, fileName)) 
... 

Это должно правильно обрабатывать случай, когда запись является символьной ссылкой и удалить его как файл. Я не уверен, что нужен chmod - он, вероятно, работает на цели ссылки, но не должно мешать обрабатывать его так же, как файл.

Тем не менее, я только что проверил и os.path.file против символической ссылки возвращает тип «вещи», на который указывает, поэтому необходима дополнительная проверка, чтобы провести различие между самой ссылкой и указываемой вещью. Также, чтобы быть переносимым, вместо добавления «/» используйте os.path.join как недавно отредактированный выше.

Смежные вопросы