rm -rf
변수가 설정되지 않아 이를 사용하는 위험한 경험을 했습니다. 그 이후로 rm -rf
글을 쓰면서 철자 오류, 띄어쓰기 등을 여러 번 교차 확인했습니다.
지금까지 저는 가능한 한 다음 관행을 따라왔습니다.
- 루트가 아닌 사용자를 사용하십시오.
*
더 구체적인 파일 경로를 사용하거나 사용하지 마십시오 .- 변수를 디렉터리 이름으로 사용하지 마세요.
따라서 제가 사용할 수 있는 표준/권장 사례나 방법 또는 스크립트가 있는지 궁금합니다 rm -rf
. 특히 *
스크립트에 수동 오류가 있는 경우에는 파괴적이지 않습니다.
고쳐 쓰다:
특정 디렉토리를 비우기 위한 지속적인 bash 유틸리티가 여기에 생성됩니다.https://github.com/g1patnaik/system_utilities/tree/dev/empty_directory
답변1
나는 이 질문이 회피에 관한 것이라고 생각하지 않지만 rm -rf
, 운영상 안전하지 않은 상태로 끝나거나 불확실한 결과를 초래할 수 있는 방식으로 사용하는 것을 피하는 것에 관한 것입니다. 철자 오류와 관련하여 다음과 같은 것을 사용할 수 있습니다.shellcheck
특정 쉘 변수(예: , 및 failglob
) 를 설정합니다 . 그래도 결국에는 코드를 읽고 실행하기 전에 일회용 또는 백업 데이터에서 테스트하는 습관을 들이십시오.bash
nounset
일을 너무 복잡하게 만드는 것은 아무 소용이 없다고 생각합니다. 모든 디렉터리 내용을 삭제하려는 경우 가장 간단한 방법은 디렉터리를 완전히 삭제하고 다시 만드는 것입니다.
rm -rf -- "$directory" && mkdir -p -- "$directory" || exit
인용문을 참고하세요 $directory
. 그렇지 않으면 의 문자열이 $directory
용어로 분할되어 foo bar
코드에서 두 이름 foo
과 변수 값이 모두 제거되기 때문에 이것이 필요합니다 bar
. 이러한 단어는 파일 이름 와일드카드 패턴으로 확장되므로 literal이라는 디렉터리를 삭제하는 것이 위험해집니다 *
. 실제 디렉토리 이름 이전에 구문 분석하기 위해 to end 옵션을 사용하여 예를 들어 또는 이라는 이름의 디렉토리를 --
처리할 수 있습니다 .-f
--version
실패하면 exit
위의 작업을 수행합니다. 코드는 자연스럽게 재생성된 디렉터리의 모든 소유권과 기타 메타데이터도 재설정합니다.rm
mkdir
또 다른 방법은 을 사용하는 것입니다 find
.
find "$directory/." ! -name . -delete
위의 내용은 비표준이지만 일반적으로 구현되는 -delete
조건자를 사용합니다. find
디렉토리 자체를 제외하고 해당 디렉토리 아래의 모든 항목을 삭제합니다. 이 경우 원래 디렉터리 항목은 다시 생성되지 않고 그대로 유지됩니다.
Portable을 사용하면 find
다음과 같이 작성할 수 있습니다.
find "$directory/." -depth ! -name . -exec rm -rf {} +
cd -
코드는 처음 실패하더라도 실행되므로 cd
스크립트가 예상치 못한 작업 디렉터리에 남아 있을 수 있습니다. 또한 코드는 숨겨진 이름을 제거하지 못하고, globbing 패턴이 너무 많은 이름으로 확장되면 "매개변수 목록이 너무 깁니다"라는 메시지와 함께 실패합니다. 일치하는 항목이 없으면 (또는 이에 상응하는) 셸 옵션 세트를 사용하여 스크립트 실행을 *
종료합니다 failglob
(디렉토리가 비어 있지 않을 것으로 예상되지만 실제로는 비어 있는 경우 이는 좋은 일입니다).
답변2
결국에는 필요하지 않을 rm -rf
대체 패턴이나 안전한 장소를 찾는 것도 좋은 생각입니다 .
예를 들어 mktemp
함수 로컬 변수에 대한 경로를 광범위하게 저장하여 모든 것이 자동으로 정리될 수 있습니다. 알 수 없는 파일의 전체 트리를 프로세스에 수집하지 않으면 해당 파일이 전혀 필요하지 않을 수도 있습니다.
/
트리를 수집하는 경우 변수가 실수로 0이 되어도 지워지지 않도록 작업 경로에 고정 접두사가 있는지 확인할 수 있습니다 .
답변3
빈 변수에 대한 가장 간단하고 일반적인 보호는 rm -rf
변수가 비어 있지 않은지 확인하는 것입니다.
if [ -n "$directory" ]; then
rm -rf "$directory"
fi
기본 경로에 추가할 때 이는 기본 경로만 전달하여 의도한 것보다 훨씬 더 많은 것을 제거하지 않도록 하는 중요한 검사입니다. 다음 예를 고려하십시오.
rm -rf "/home/user/$Dir"
변수가 $Dir
비어 있으면 명령은 입니다 rm -rf /home/user/
.
-f
삭제하려는 항목에 대해 자세히 알고 있는 경우 경로가 파일 또는 디렉터리 인지 확인할 수도 있습니다 -d
.
man test
표현식 테스트에 대한 대부분의 정보는 참고자료를 참조하십시오.
인용은 경로 이름을 2개의 매개변수로 분할하여 경로 이름에 공백이 나타나는 것을 방지합니다.