비어 있지 않은 폴더를 삭제하려고하면 '액세스가 거부되었습니다'오류가 발생합니다. 시도 할 때 다음 명령을 사용했습니다 os.remove("/folder_name")
..
비어 있지 않은 폴더 / 디렉토리를 제거 / 삭제하는 가장 효과적인 방법은 무엇입니까?
rm -rf
행동을 참조하십시오 stackoverflow.com/questions/814167/...
비어 있지 않은 폴더를 삭제하려고하면 '액세스가 거부되었습니다'오류가 발생합니다. 시도 할 때 다음 명령을 사용했습니다 os.remove("/folder_name")
..
비어 있지 않은 폴더 / 디렉토리를 제거 / 삭제하는 가장 효과적인 방법은 무엇입니까?
rm -rf
행동을 참조하십시오 stackoverflow.com/questions/814167/...
답변:
import shutil
shutil.rmtree('/folder_name')
의도적으로 rmtree
읽기 전용 파일이 포함 된 폴더 트리 에서는 실패합니다. 읽기 전용 파일이 포함되어 있는지 여부에 관계없이 폴더를 삭제하려면 다음을 사용하십시오.
shutil.rmtree('/folder_name', ignore_errors=True)
rmtree
: 읽기 전용 파일이있는 경우 실패합니다 stackoverflow.com/questions/2656322/...
에서 파이썬 문서 에 os.walk()
:
# Delete everything reachable from the directory named in 'top',
# assuming there are no symbolic links.
# CAUTION: This is dangerous! For example, if top == '/', it
# could delete all your disk files.
import os
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
import shutil
shutil.rmtree(dest, ignore_errors=True)
ignore_errors=True
문제를 해결합니다.
onerror
매개 변수가 대신 사용됩니다 ignore_errors
. 이렇게하면 읽기 전용 파일이 무시되지 않고 삭제됩니다.
rmtree()
방법이 무시됩니다.
에서 docs.python.org :
이 예는 일부 파일에 읽기 전용 비트가 설정된 Windows에서 디렉토리 트리를 제거하는 방법을 보여줍니다. 읽기 전용 비트를 지우고 제거를 다시 시도하기 위해 onerror 콜백을 사용합니다. 후속 실패는 전파됩니다.
import os, stat import shutil def remove_readonly(func, path, _): "Clear the readonly bit and reattempt the removal" os.chmod(path, stat.S_IWRITE) func(path) shutil.rmtree(directory, onerror=remove_readonly)
import os
import stat
import shutil
def errorRemoveReadonly(func, path, exc):
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
# change the file to be readable,writable,executable: 0777
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
# retry
func(path)
else:
# raiseenter code here
shutil.rmtree(path, ignore_errors=False, onerror=errorRemoveReadonly)
ignore_errors가 설정되면 오류가 무시됩니다. 그렇지 않으면, onerror가 설정되면 인수 (func, path, exc_info)로 오류를 처리하기 위해 호출됩니다. 여기서 func는 os.listdir, os.remove 또는 os.rmdir입니다. path는 실패한 함수에 대한 인수입니다. exc_info는 sys.exc_info ()에 의해 반환 된 튜플입니다. ignore_errors가 false이고 onerror가 None이면 예외가 발생합니다.
kkubasik의 답변을 바탕으로 폴더를 제거하기 전에 폴더가 있는지 확인하십시오.
import shutil
def remove_folder(path):
# check if folder exists
if os.path.exists(path):
# remove if exists
shutil.rmtree(path)
else:
# throw your exception to handle this special scenario
raise XXError("your exception")
remove_folder("/folder_name")
확실하다면, 전체 디렉토리 트리를 삭제하고 더 이상 디렉토리 내용에 관심이 없다면 전체 디렉토리 트리를 크롤링하는 것은 어리 석음입니다 ... 파이썬에서 네이티브 OS 명령을 호출하면됩니다. 더 빠르고 효율적이며 메모리 소비가 적습니다.
RMDIR c:\blah /s /q
또는 * nix
rm -rf /home/whatever
파이썬에서는 코드가 다음과 같습니다.
import sys
import os
mswindows = (sys.platform == "win32")
def getstatusoutput(cmd):
"""Return (status, output) of executing cmd in a shell."""
if not mswindows:
return commands.getstatusoutput(cmd)
pipe = os.popen(cmd + ' 2>&1', 'r')
text = pipe.read()
sts = pipe.close()
if sts is None: sts = 0
if text[-1:] == '\n': text = text[:-1]
return sts, text
def deleteDir(path):
"""deletes the path entirely"""
if mswindows:
cmd = "RMDIR "+ path +" /s /q"
else:
cmd = "rm -rf "+path
result = getstatusoutput(cmd)
if(result[0]!=0):
raise RuntimeError(result[1])
shutil.rmdir
은 운영 체제 유형으로부터 사용자를 격리시키는 것입니다.
위의 답변을 완료하기 위해 일부 Python 3.5 옵션이 있습니다. (여기서 그들을 찾고 싶었을 것입니다).
import os
import shutil
from send2trash import send2trash # (shutil delete permanently)
비어있는 경우 폴더 삭제
root = r"C:\Users\Me\Desktop\test"
for dir, subdirs, files in os.walk(root):
if subdirs == [] and files == []:
send2trash(dir)
print(dir, ": folder removed")
이 파일이 포함 된 폴더도 삭제
elif subdirs == [] and len(files) == 1: # if contains no sub folder and only 1 file
if files[0]== "desktop.ini" or:
send2trash(dir)
print(dir, ": folder removed")
else:
print(dir)
.srt 또는 .txt 파일 만 포함 된 폴더 삭제
elif subdirs == []: #if dir doesn’t contains subdirectory
ext = (".srt", ".txt")
contains_other_ext=0
for file in files:
if not file.endswith(ext):
contains_other_ext=True
if contains_other_ext== 0:
send2trash(dir)
print(dir, ": dir deleted")
크기가 400kb 미만인 경우 폴더를 삭제하십시오.
def get_tree_size(path):
"""Return total size of files in given path and subdirs."""
total = 0
for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False):
total += get_tree_size(entry.path)
else:
total += entry.stat(follow_symlinks=False).st_size
return total
for dir, subdirs, files in os.walk(root):
If get_tree_size(dir) < 400000: # ≈ 400kb
send2trash(dir)
print(dir, "dir deleted")
if files[0]== "desktop.ini" or:
"pure pathlib"접근 방식을 추가하고 싶습니다 :
from pathlib import Path
from typing import Union
def del_dir(target: Union[Path, str], only_if_empty: bool = False):
target = Path(target).expanduser()
assert target.is_dir()
for p in sorted(target.glob('**/*'), reverse=True):
if not p.exists():
continue
p.chmod(0o666)
if p.is_dir():
p.rmdir()
else:
if only_if_empty:
raise RuntimeError(f'{p.parent} is not empty!')
p.unlink()
target.rmdir()
이것은 순서 Path
가 정해져 있다는 사실에 의존하며, 더 긴 경로는 항상처럼 짧은 경로를 따라 정렬됩니다 str
. 따라서 디렉토리는 파일보다 우선합니다. 정렬 을 반대로 바꾸면 파일이 해당 컨테이너보다 먼저 나오므로 패스별로 하나씩 링크를 해제 / rmdir 할 수 있습니다.
혜택:
pathlib
Python 3.6에서 약속하는 것입니다. 위의 작업은 Windows에서 실행되지 않는다고 명시되어 있지 않습니다)def deleteDir(dirPath):
deleteFiles = []
deleteDirs = []
for root, dirs, files in os.walk(dirPath):
for f in files:
deleteFiles.append(os.path.join(root, f))
for d in dirs:
deleteDirs.append(os.path.join(root, d))
for f in deleteFiles:
os.remove(f)
for d in deleteDirs:
os.rmdir(d)
os.rmdir(dirPath)
shutil
모듈 을 사용하지 않으려면 모듈을 사용하면 os
됩니다.
from os import listdir, rmdir, remove
for i in listdir(directoryToRemove):
os.remove(os.path.join(directoryToRemove, i))
rmdir(directoryToRemove) # Now the directory is empty of files
os.remove
디렉토리를 제거 할 수 없으므로 서브 디렉토리 OsError
가 directoryToRemove
포함되어 있으면 증가 합니다 .
10 년 후 Python 3.7과 Linux를 사용하는 방법은 여전히 다른 방법입니다.
import subprocess
from pathlib import Path
#using pathlib.Path
path = Path('/path/to/your/dir')
subprocess.run(["rm", "-rf", str(path)])
#using strings
path = "/path/to/your/dir"
subprocess.run(["rm", "-rf", path])
본질적으로 파이썬의 하위 프로세스 모듈을 $ rm -rf '/path/to/your/dir
사용하여 동일한 작업을 수행하기 위해 터미널을 사용하는 것처럼 bash 스크립트를 실행합니다 . 완전히 파이썬은 아니지만 완료됩니다.
내가 pathlib.Path
예제를 포함시킨 이유는 내 경험상 변경되는 많은 경로를 다룰 때 매우 유용하기 때문입니다. pathlib.Path
모듈 을 가져오고 최종 결과를 문자열로 변환하는 추가 단계 는 종종 개발 시간에 저비용입니다. Path.rmdir()
비어 있지 않은 디렉토리를 명시 적으로 처리하기 위해 arg 옵션을 사용하면 편리합니다 .
rmtree
이와 같은 폴더에 숨겨진 문제가 발생하여이 방법으로 전환했습니다 .vscode
. 이 폴더는 텍스트 파일로 감지되었으며이 파일이 busy
삭제 되었으며 삭제할 수 없다는 오류 가 표시됩니다.
폴더가 존재하지 않더라도 ( Charles Chow의 답변 에서 경쟁 조건을 피할 수 있음) 폴더를 삭제 하지만 다른 일이 잘못되었을 때 여전히 오류가 발생합니다 (예 : 권한 문제, 디스크 읽기 오류, 파일이 디렉토리가 아닙니다)
Python 3.x의 경우 :
import shutil
def ignore_absent_file(func, path, exc_inf):
except_instance = exc_inf[1]
if isinstance(except_instance, FileNotFoundError):
return
raise except_instance
shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)
파이썬 2.7 코드는 거의 같습니다 :
import shutil
import errno
def ignore_absent_file(func, path, exc_inf):
except_instance = exc_inf[1]
if isinstance(except_instance, OSError) and \
except_instance.errno == errno.ENOENT:
return
raise except_instance
shutil.rmtree(dir_to_delete, onerror=ignore_absent_file)
os.walk를 사용하면 3 개의 one-liner Python 호출로 구성된 솔루션을 제안합니다.
python -c "import sys; import os; [os.chmod(os.path.join(rs,d), 0o777) for rs,ds,fs in os.walk(_path_) for d in ds]"
python -c "import sys; import os; [os.chmod(os.path.join(rs,f), 0o777) for rs,ds,fs in os.walk(_path_) for f in fs]"
python -c "import os; import shutil; shutil.rmtree(_path_, ignore_errors=False)"
첫 번째 스크립트 chmod는 모든 하위 디렉토리이고, 두 번째 스크립트 chmod는 모든 파일입니다. 그런 다음 세 번째 스크립트는 장애없이 모든 것을 제거합니다.
Jenkins 작업의 "Shell Script"에서 이것을 테스트했습니다 (SCM에 새로운 Python 스크립트를 저장하고 싶지 않기 때문에 한 줄 솔루션을 검색 한 이유입니다) .Linux 및 Windows에서 작동했습니다.
pathlib
하면 처음 두 단계를 하나로 결합 할 수 있습니다.[p.chmod(0o666) for p in pathlib.Path(_path_).glob("**/*")]
간단하게 os.system 명령을 사용할 수 있습니다.
import os
os.system("rm -rf dirname")
명백히, 실제로이 작업을 수행하기 위해 시스템 터미널을 호출합니다.