2016-07-16 23 views
0

Also muss ich ein Verzeichnis, das nicht leer ist reinigen. Ich habe die folgenden function.For Testzwecken habe ichLöschen Sie ein Verzeichnis, das nicht leer ist auf 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 

Ich habe versucht, eine JDK-Installation zu entfernen versucht rmtree und rmdir zu verwenden, aber es funktioniert nicht.

Der Fehler ich rmtree wurde unter Verwendung ist:

OSError: Cannot call rmtree on a symbolic link

Und das ist der Fehler, den ich bekam, als ich rmdir verwendet:

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

Der Code funktioniert einwandfrei unter Windows. Aber aus irgendeinem Grund schlägt es auf Linux fehl.

+0

Sie weisen rmtree auf einen symbolischen Link, kein Verzeichnis hinzuzufügen. https://en.wikipedia.org/wiki/Symbolic_link – iScrE4m

+0

Wenn es ein symbolischer Link ist, denke ich 'os.unlink (...)' ist alles was Sie brauchen. (Um das klarzustellen, wird nur der symbolische Link entfernt. Es wird nichts gelöscht, auf das der symbolische Link zeigt.) – smarx

+0

IIRC, 'os.unlink' sollte auch Dateien löschen. – kronenpj

Antwort

1

kronenpj danke, das war die Idee. Aber wenn Sie einen Symlink haben, versucht es zu löschen ist wie eine normale Datei und schlägt fehl. Ich hatte eine neue elif aufzuwerten und die unlink Option für die Symlink

 
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

Absolut richtig, ich war mir nicht sicher, ob 'remove()' Symlinks richtig behandeln würde oder nicht. – kronenpj

2

Sie treffen auf einen der Unterschiede zwischen der Art und Weise, wie Windows und Linux (UNIX wirklich) mit Dateisystemen umgehen. Ich glaube, das Hinzufügen eines zusätzlichen Fall, um Ihren Code wird zumindest helfen:

... 
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)) 
... 

Dies sollte richtig den Fall behandeln, wo der Eintrag einen Symlink ist, und entfernen Sie es einfach wie eine Datei. Ich bin nicht sicher, ob die chmod notwendig ist - es funktioniert wahrscheinlich auf das Ziel der Verbindung, aber es sollte nicht schaden, es genauso zu behandeln wie eine Datei.

Allerdings habe ich gerade überprüft und os.path.file gegen eine symbolische Verbindung gibt den Typ der "Sache", auf die verwiesen wird, so dass die zusätzliche Prüfung erforderlich ist, um zwischen der Verknüpfung selbst und der Sache zu unterscheiden. Um portabel zu sein, anstatt "/" anzuhängen, verwenden Sie os.path.join wie oben beschrieben.