찾기를 사용하여 스크립트 정리 - 해당 파일이나 디렉토리가 없습니다.

찾기를 사용하여 스크립트 정리 - 해당 파일이나 디렉토리가 없습니다.

다음 명령을 사용하여 하위 볼륨 세트를 찾아 삭제합니다.

find /.snapshots/ -name backup-* -type d -exec btrfs subvolume delete {} \;

작동하지만 find에서 예상치 못한 결과가 나타납니다.

Delete subvolume (no-commit): '/.snapshots/backup-24-11-2021'    
find: ‘/.snapshots/backup-24-11-2021’: No such file or directory    
Delete subvolume (no-commit): '/.snapshots/backup-25-11-2021'    
find: ‘/.snapshots/backup-25-11-2021’: No such file or directory
    

저는 유닉스 전문가가 아니기 때문에 이것이 약간 혼란스럽습니다. 왜 이런 일이 발생합니까?

답변1

find가 도착 하면 /.snapshots/backup-24-11-2021의 지시에 따라 디렉터리인지 확인합니다 -type d. 디렉터리이므로 지침을 따르세요 find. 완료되면 디렉터리에 방금 도달했으므로 해당 디렉터리로 다시 돌아옵니다. 결국, 디렉토리로의 재귀는 .그러나 그 디렉토리는 방금 삭제되었습니다. 따라서 문제를 발견하고 보고하십시오.btrfs subvolume delete /.snapshots/backup-24-11-2021-exec …findfindbtrfs subvolume deletefind

find삭제하려는 스냅샷 아래에서 반복되지 않도록 알려줍니다 . 이는 일반적으로 삭제할 전체 디렉토리 트리를 찾는 데 사용됩니다.

find /.snapshots/ -name 'backup-*' -type d -exec btrfs subvolume delete {} \; -prune

(참고: 절 주위에 누락된 따옴표도 수정했습니다 -name. 따옴표가 없으면 backup-*실행 시 확장되므로 현재 디렉터리에 일치하는 파일이 있거나 사용 중인 셸에 오류가 있는 경우 명령은 작업을 수행하지 않습니다. 전 세계적으로 일치하지 않을 것으로 find예상backup-*

그러나 실제로 이것은 완전히 잘못된 명령일 수 있습니다. find아래를 둘러보라고 지시합니다 /.snapshots. 예를 들어, /.snapshots/saved-for-posterity/usr/src/backup-app명령이 findcall 로 지시하는 디렉터리가 있는 경우 btrfs subvolume delete /.snapshots/saved-for-posterity/usr/src/backup-app이는 의미가 없습니다. 모든 스냅샷이 의 하위 디렉터리라고 가정하고 추가 재귀를 방지하려면 다음을 /.snapshots전달하세요 .-maxdepth 1

find /.snapshots/ -maxdepth 1 -name 'backup-*' -type d -exec btrfs subvolume delete {} \;

유일한 차이점은

btrfs subvolume delete /.snapshots/backup-*

현재 백업이 없는 경우 btrfs subvolume delete리터럴 매개변수로 호출됩니다 ./.snapshots/backup-*

답변2

find디렉터리 내부를 살펴보기 전에 디렉터리를 삭제했기 때문에 오류 메시지가 표시됩니다 . find현재 삭제된 디렉토리가 포함된 디렉토리 작업이 완료되면 eg 를 입력하려고 시도 하지만 backup-24-11-2021해당 디렉토리가 사라졌기 때문에 "해당 파일이나 디렉토리가 없습니다"라는 오류와 함께 실패합니다.

유틸리티가 디렉토리에 대해 깊이 우선 검색을 수행하도록 하는 with 를 사용하여 -depth이 문제를 해결할 수 있습니다. 예를 들어 찾기 및 삭제는 find해당 경로 아래의 다른 모든 디렉터리를 본 후에만 발생합니다 ./.snapshots/backup-25-11-2021find

find /.snapshots -depth -name 'backup-*' -type d \
    -exec btrfs subvolume delete {} \;

-name또한 파일 이름 와일드카드가 포함되어 있으므로 테스트 매개변수를 인용해야 합니다 .

이를 수행하는 또 다른 방법은 경로가 발견되면 검색 트리에서 해당 경로를 제거하여 해당 경로에 더 깊이 들어가려는 시도가 이루어지지 -prune않도록 하는 것입니다.findfind

find /.snapshots -name 'backup-*' -type d -prune \
    -exec btrfs subvolume delete {} \;

세 번째 접근 방식은 모든 backup-*디렉터리가 항상 다음 바로 아래에 있는 경우입니다 /.snapshots.find

shopt -s nullglob
for dir in /.snapshots/backup-*; do
    btrfs subvolume delete "$dir"
done

btrfs subvolume delete위의 쉘 루프는 패턴과 일치하는 모든 디렉토리를 호출합니다 /.snapshots/backup-*. bash셸 에서 nullglob셸 옵션을 설정하면 셸은 확장되지 않은 패턴을 그대로 두지 않고 일치하지 않는 와일드카드 패턴을 제거합니다.

명령이 btrfs subvolume delete여러 경로 이름을 인수로 사용할 수 있는 경우 다음을 수행해야 할 수도 있습니다.

shopt -s failglob
btrfs subvolume delete /.snapshots/backup-*

... 주어진 와일드카드 패턴과 일치하는 경로 이름이 없으면 쉘 failglob의 쉘 옵션은 명령 실행을 방지합니다.bash

관련 정보