find
특정 기준과 일치하는 파일을 삭제하는 데 사용하는 방법 :
find -type f [more criteria] -delete
일반적으로 이것은 잘 작동하지만 다른 사용자가 만든 하위 디렉터리에 문제가 있습니다. 제가 아는 한, 그 사용자가 파일 삭제를 허용합니까?상위 디렉토리에 대한 내 권한에 따라 다릅니다.. 따라서 다른 사용자가 만든 하위 디렉터리에 포함된 파일에 대해서는 위 명령이 실패합니다.
fbrucker@host /tmp $ ls -lh
total 4,0K
drwxrwxr-x 2 root root 4,0K Jun 15 11:44 foo/
fbrucker@host /tmp $ ls -lh foo/
total 0
-rw-rw-r-- 1 fbrucker fbrucker 0 Jun 15 11:44 a
-rw-rw-r-- 1 root root 0 Jun 15 11:44 b
fbrucker@host /tmp $ find -type f -delete
find: cannot delete ‘./foo/b’: Permission denied
find: cannot delete ‘./foo/a’: Permission denied
괜찮습니다. 파일을 삭제할 수는 없지만 권한이 부족하면 find
0이 아닌 상태로 종료됩니다. 나는 이런 상황을 피하고 싶다.
삭제할 수 없는 파일을 삭제하기 전에 어떻게 필터링할 수 있나요?
오류 메시지를 필터링하면 됩니다.아니요여전히 0이 아닌 종료 코드가 남으므로 이것으로 충분합니다. 또한 종료 코드를 완전히 무시하는 것은 다른 오류를 포착하고 싶기 때문에 작동하지 않습니다(실제 find
명령은 더 복잡합니다. 예를 find /somedir -type f -delete
들어아니요/somedir
존재하지 않을 때 발생하는 오류는 무시합니다.)
find
파일(예:,,)에 대한 권한을 테스트한다는 것을 알고 있지만 -perm
여기에는 적용되지 않는 것 같습니다. 예를 들어,-readable
-writable
fbrucker@host /tmp $ find -type f -writable
./foo/a
foo/a
필요한 권한이 없어서 삭제할 수 없는데도 foo
.
-deletable
테스트 같은 것을 찾고 있는데 존재하지 않는 것 같습니다.
답변1
예, 상위 디렉터리에 대한 쓰기 권한이 필요하며 해당 디렉터리에 비트가 설정된 경우 링크를 t
해제하려는 디렉터리 또는 파일의 소유자여야 합니다. 이 모든 것은 ACL과 같은 다른 보안 제어가 없고 파일이 위치한 FS는 읽기 전용이 아니므로제거 가능검사는 더 복잡합니다.
for -readable
// -writable
( -executable
비표준) find
해당 access(R_OK/W_OK/X_OK)
시스템 호출을 사용할 수 있지만 이에 상응하는 것은 없습니다.풀리다하나의 문서.
GNU find
4.9.0 이상을 사용하면 다음과 같이 근사할 수 있습니다.
find . -depth -type d -writable '(' -uid "$EUID" -o ! -perm -o=t ')' -print0 |
find -files0-from - -mindepth 1 -maxdepth 1 -type f -delete
zsh
( 또는 과 같은 bash
쉘 설정을 가정합니다 $EUID
. 그렇지 않은 경우 해당 을 사용하십시오 "$(id -u)"
).
이렇게 하면 소유한 파일이 소유하지 않은 -bit 디렉터리에 남게 되며 t
해당 파일을 별도로 처리해야 합니다.
find . -depth -type d -writable ! -uid "$EUID" -perm -o=t -print0 |
find -files0-from - -mindepth 1 -maxdepth 1 -type f -uid "$EUID" -delete
pipefail
첫 번째 find
.
이전 버전의 GNU에서는 find
언제든지 다음을 수행할 수 있습니다.
find . -depth -type d -writable '(' -uid "$EUID" -o ! -perm -o=t ')' -exec sh -c '
exec find "$@" -mindepth 1 -maxdepth 1 -type f -delete
' sh {} +
액세스 권한으로 인한 파일 링크 해제 실패를 무시하는 것이 요점이라면 다음과 같이 할 수 있습니다.
set -o pipefail
find . -depth -type f -print0 |
perl -l -0ne '
unless (unlink($_) || $!{EACCES}) {
warn "$_: $!\n";
$ret = 1;
}
END {exit $ret}'
답변2
한 가지 해결 방법 은 호출의 종료 코드가 무시되므로 대신 -exec rm {} \;
사용 하는 것입니다 .-delete
find
-exec