2016-07-16 7 views
0

したがって、空でないディレクトリをきれいにする必要があります。 私はrmtreeとrmdirをを使用しようとした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 

を削除しようとした次function.Forテストの理由を作成しているが、それは失敗します。

私は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'

コードは、Windows上で正しく動作します。しかし何らかの理由でLinuxで失敗します。

+0

のための新しいのelifを追加し、リンク解除のオプションを追加する必要がありました。 https://en.wikipedia.org/wiki/Symbolic_link – iScrE4m

+0

シンボリックリンクの場合は、 'os.unlink(...)'だけで十分だと思います。 (シンボリックリンクを削除するだけで、シンボリックリンクが指し示すものは削除されません) – smarx

+0

IIRC、 'os.unlink'はファイルも削除する必要があります。 – kronenpj

答えて

1

kronenpjありがとう、それはアイデアでした。しかし、あなたが削除しようとしているシンボリックリンクがある場合、それは通常のファイルであり、失敗します。私はあなたがシンボリックリンクではなく、ディレクトリでrmtreeを指しているシンボリックリンク

 
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は本当に)がファイルシステムを処理する方法の違いの1つに遭遇しています。

... 
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を使用してください。

関連する問題