find ~ -name delete_me -type f -print0 | xargs -0 /bin/rm -f
Q1.무슨 뜻 -print0
이고 왜 필요한가요?
Q2.왜 /bin/rm
? 왜 안되나요 rm -f
?
이 명령은 ~
디렉터리에서 일치하는 파일만 삭제하며, 하위 디렉터리나 하위 디렉터리에서는 일치하는 파일을 삭제하지 않습니다.
Q3. 하위 디렉터리에서도 일치하는 모든 파일을 찾아 삭제하도록 이를 수정하려면 어떻게 해야 합니까?
Q4. 특정 디렉토리를 찾을 수 없도록 수정하는 방법은 무엇입니까?
감사해요
답변1
비표준
-print0
술어는 "개행 문자 대신 종료 널 문자로 발견된 파일의 경로 이름을 인쇄한다"는 의미입니다. 이는 개행 문자가 포함된 파일 이름을 처리할 수 있도록 하기 위한 것입니다(Unix 시스템에서는 허용되지만 nul 문자는 Unix 파일 이름의 일부가 될 수 없습니다).find
사용된 명령의 출력을 읽는 명령은-print0
항목이 null로 종료된다는 점에 유의해야 합니다. 이-0
옵션을 사용하면xargs
null로 끝나는 항목을 읽을 수 있습니다.이는 필수가 아닙니다. 어느 것도 아니다
find "$HOME" -name delete_me -type f -delete
더 이상 표준이 아닙니다.
find "$HOME" -name delete_me -type f -exec rm {} +
이 두 명령 은
-print0
명령과 동일한 작업을 수행하며 기본적으로 사용해야 합니다xargs
.xargs
이 유틸리티는 파일이나 다른 명령에서 매개변수를 읽을 때 유용할 수 있습니다. 사용시에는find
내장된 시설을 이용하는 것이-exec
더욱 안전합니다 . 거기예동시 배치를 시작하는 유틸리티와 같이 특정 구현에서xargs
수행할 수 있는 작업과 수행할 수 없는 작업이 있습니다 .-exec
그러나 이 연습에서는 이 방법이 사용되지 않습니다.변수처럼 동작하기 때문에 쉘 스크립트에서 사용하는 것이 더 좋지만
"$HOME"
그렇지 않습니다.~
$HOME
~
또한 이
-f
옵션이 필요하지 않을 수도 있습니다. 유틸리티를rm
피하기 위해 사용됩니다.rm
실패하다(진단 메시지 및 0이 아닌 종료 상태 포함) 지정된 경로 이름이 없거나rm
제거할 경로 이름 없이 호출되는 경우. 또한 이전-i
(대화형 모드) 옵션을 재정의합니다. 그러나 여기 명령줄-i
에는 옵션이 없으며 해당 경로를 찾는 데rm
사용된 경로 이름은find
존재하도록 보장됩니다(파일이 실행 중에 다른 프로세스에 의해 실제로 삭제되는 경쟁 조건이 없는 한 삭제find
실행자에 의해)find
.rm
find
변수 값에 합리적인 유틸리티 경로 세트가 포함되어 있다는 보장이 없는
rm
한 전체 경로를 사용할 이유가 없습니다 .PATH
손상은 흔하지 않으며PATH
절대 경로를 사용하여 유틸리티를 작성하는 스크립트는 다른 시스템으로 이동하면 쉽게 손상될 수 있습니다.실제로 홈 디렉토리의 모든 하위 디렉토리로 반복되었습니다.
검색 트리에서 피하려는 디렉토리를 제거하십시오. 예를 들어, 다음과 같은 이름의 모든 디렉토리를 피하려면
avoid
:find "$HOME" -name avoid -prune -o -name delete_me -type f -exec rm {} +
깊이 우선 검색을
-delete
의미하기 때문에 여기서는 사용할 수 없습니다 .-depth
깊이 우선 검색을 사용하면 디렉터리가 검색 트리에서 제거되어야 한다는avoid
것을 알기 전에 그 안에 있는 모든 하위 디렉터리와 파일에 액세스합니다.avoid
또 다른 예: 입력하지 마세요특정한목차
$HOME/dir/save_me
:find "$HOME" -path "$HOME/dir/save_me" -prune -o -name delete_me -type f -exec rm {} +
답변2
Q1.-print0은 무엇을 의미하며 왜 필요한가요?
좋은 출발점은 매뉴얼을 확인하는 것입니다. 터미널에 입력하면 man find
자세한 설명을 볼 수 있습니다. 일반적으로 Google에서 "man find"를 검색하여 웹에서 동일/유사한 매뉴얼 페이지를 얻을 수도 있습니다.
find 매뉴얼에는 다음과 같이 나와 있습니다 -print0
.
표준 출력에 전체 파일 이름을 인쇄하고 그 뒤에 널 문자(-print에서 사용하는 개행 문자 대신)를 인쇄합니다. 이를 통해 find 출력을 처리하는 프로그램이 개행 또는 기타 유형의 공백이 포함된 파일 이름을 올바르게 해석할 수 있습니다.
따라서 이것은 각 파일 이름 뒤에 null 문자를 쓰고 xargs는 -0
각 항목이 로 끝날 것으로 예상하여 읽습니다 -0
.
Q2. 왜 /bin/인가요? 왜 rm -f만 사용하면 안 되나요?
귀하의 질문에 따르면 이것이 왜 수행되는지 명확하지 않습니다.
여기에는 타당한 이유가 없는 것 같습니다. 때때로 이 작업이 수행되는 이유 중 하나는 다음을 허용하는 것입니다.길환경 변수가 잘못 설정되었습니다. 이는 에서 명령을 실행할 때 일반적입니다 cron
.
그러나 이 경우 다른 명령( find
및 xargs
)이 정규화되지 않았기 때문에 도움이 되지 않습니다. 그것은해야한다:
/bin/find ~ -name delete_me -type f -print0 | /usr/xargs -0 /bin/rm -f
또 다른 (가능성이 거의 없는) 유일한 이유는 시스템에 두 개의 서로 다른 rm
명령이 있고 어느 명령을 지정해야 하는지입니다. 하지만 그럴 가능성은 거의 없습니다.
Q3. 하위 디렉터리에서도 일치하는 모든 파일을 찾아 삭제하도록 이를 수정하려면 어떻게 해야 합니까?
이미 그렇게 했습니다.
Q4. 특정 디렉토리를 찾을 수 없도록 수정하는 방법은 무엇입니까?
이 -prune
옵션을 사용하여 이 디렉터리(및 해당 하위 디렉터리)를 건너뛸 수 있습니다.
# Just editing your version...
find "$HOME" -name exclude_this_dir -prune -o -name delete_me -type f -print0 | xargs -0 /bin/rm -f
# More succinctly
find "$HOME" -name exclude_this_dir -prune -o -name delete_me -type f -exec rm -f {} +