사용자가 소유하지 않은 디렉토리에서 "chown" 명령이 "-R" 플래그와 함께 반복적으로 작동하지 않는 이유는 무엇입니까?

사용자가 소유하지 않은 디렉토리에서 "chown" 명령이 "-R" 플래그와 함께 반복적으로 작동하지 않는 이유는 무엇입니까?

체계:x86_64 리눅스 5.13.19-2-MANJARO.

사용자가 소유한 일부 디렉토리가 포함된 "~/.local/share/Trash/expunged"에 이상한 디렉토리가 있습니다.아무도. 루트로 다음 명령을 실행해 보았습니다.

rm -rf pathToWeirdDirectory

그러면 다음과 같은 오류 메시지가 생성됩니다.

rm: 'pathToWeirdDirectory'를 삭제할 수 없습니다. 정의된 데이터 유형에 비해 값이 너무 큽니다.

다음을 사용하여 디렉터리 소유권을 변경한 후

chown me:me pathToWeirdDirectory

마침내 디렉토리를 성공적으로 삭제했습니다. 여러 파일을 포함하는 여러 하위 디렉터리가 있는 이러한 유형의 디렉터리도 있습니다. 다음 명령을 실행하려고 합니다.

chown -R me:me pathToSecondWeirdDirectory

그러면 다음과 같은 오류 메시지가 생성됩니다.

chown: 'pathToSeconWeirdDirectory/subdirectory1/subdirectory2' 디렉터리를 읽을 수 없습니다. 권한이 거부되었습니다.

내 경우에는 "-R" 플래그가 특정 디렉터리의 소유권을 재귀적으로 변경했기 때문에 다음 테스트 사례를 만들었습니다.

directory/
    file
    subdirectory/
    file2

사용자가 소유. "chown -R root:root"를 사용하여 예상대로 모든 하위 디렉터리와 파일을 포함하여 소유권을 성공적으로 변경했습니다.

질문:사용자가 소유한 디렉터리에 대해 "-R" 플래그를 사용하여 "chown" 명령이 반복적으로 작동하지 않는 이유는 무엇입니까?아무도? 사용자가 소유한 파일을 삭제할 수 없는 이유는 무엇입니까?아무도~처럼뿌리?

편집하다:의견에 대한 응답으로 "pathToSecondWeirdDirectory"의 전체 이름을 제공하고 싶습니다.

~/.local/share/Trash/expunged/294376611/5e5a7b41-3df4-4b2f-b7ac-f57d09ed1823/.sage/matplotlib-1.5.1

다른 예시

~/.local/share/Trash/expunged/294376611/5e5a7b41-3df4-4b2f-b7ac-f57d09ed1823/.sage/R

편집 2:Marcus가 훌륭한 답변을 제공한 후 동일한 기술을 사용하여 디버깅을 더 수행했습니다. 단일 디렉토리를 chown하는 것은 예상대로 작동합니다. chown에 -R을 사용하면 실패합니다. 출력을 비교했는데 마지막 몇 줄까지 동일했습니다. 그들은 다음과 같습니다:

마을:

close(8)                                = 0
close(5)                                = 0
close(6)                                = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
newfstatat(AT_FDCWD, "security", {st_mode=S_IFDIR|0700, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchownat(AT_FDCWD, "security", 60202, 60202, 0) = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

존-R

close(8)                                = 0
close(5)                                = 0
close(6)                                = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
newfstatat(AT_FDCWD, "startup", {st_mode=S_IFDIR|0700, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "startup", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2998, ...}, AT_EMPTY_PATH) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2998
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "chown: ", 7)                  = 7
write(2, "cannot read directory 'startup'", 31) = 31
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": Permission denied", 19)     = 19
write(2, "\n", 1)                       = 1
close(1)                                = 0
close(2)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

답변1

추가 디버깅 없이는 확실히 알 수 없지만 이는 Linux에서 예전에 겪었던(그리고 지금도 발생하는) stat/stat64 문제처럼 보입니다.

기본적으로 fstat시스템 호출은 "이 파일이 디렉토리입니까?"와 같은 질문에 사용됩니다. (재귀적으로 삭제하려는 경우 아는 것이 매우 중요함), "심볼릭 링크입니까?", "크기는 얼마입니까?".

마지막 부분이 흥미로워지는 부분입니다. 시스템 호출에는 struct stat이 모든 유형 정보에 대한 필드가 포함된 a에 대한 포인터가 필요합니다. 처음에는 파일 크기 정수가 32비트입니다. 이제 파일이 이보다 클 수 있습니다. 따라서 64비트 정보를 제공하려면 새 호출이 필요합니다.

이제 32비트 변수가 들어갈 수 있는 것보다 큰 파일에 32비트 통계 변형을 사용할 때 어떻게 해야 합니까? 분명히, 실수로 65GB 파일의 크기가 1GB에 불과하다고 생각하지 않도록 오류 조건이 있어야 합니다. 이 오류가 error// 에 전달되면 표시되는 오류 메시지가 strerror정확하게 인쇄됩니다.perror

물론, 파일 통계의 다른 부분이 반환하려는 유형에 맞지 않는 경우(또는 최대 페이지 수를 초과하는 경우 및 기타 여러 경우)에도 동일한 메커니즘이 적용됩니다.

이제 재미있는 부분이 나옵니다. 이것은 상대적으로 현대적인 것이 아닐 것입니다.

/usr/bin/rm: ELF 64비트 LSB 파이 실행 파일, x86-64, 버전 1(SYSV), 동적으로 연결됨,interpreter/lib64/ld-linux-x86-64.so.2, BuildID[sha1] =5d1d8b77d21f9362855e93f8cff5fc685127a26f , GNU/Linux 4.4.0에서는 제거됨

사용 중오래된 fstat[at]시스템 호출. 당신은 시도 할 수 있습니다:

cd /tmp
touch base
strace -o log.strace -e /stat rm base
grep '"base"' log.strace

~해야 한다아마도Yield call 을 사용 newfstatat하면 확실히 64비트 숫자를 처리합니다.

따라서 이러한 지식을 바탕으로 이제 이상한 디렉터리를 삭제해 보겠습니다.

strace -o /tmp/log.strace rm -r /path/to/one/single_one/of/the/undeletable_directories

그리고 로그 하단으로 스크롤합니다. 오류 메시지를 인쇄하려면 몇 줄의 호출이 필요하지만 위의 호출이 결과 호출이어야 합니다 EOVERFLOW(힌트: 해당 문자열을 검색하세요!). 내 가정은 이것이다.아니요일반적인 통계 호출이지만 openat호출일 수도 있고 다른 이유로 실패할 수도 있습니다.


¹ 를 실행하고 gdb --args rm /path/to/weirddirectory에 대한 모든 호출에 중단점을 설정하고 error, 그래도 작동하지 않으면 에 대한 모든 호출에 중단점을 설정합니다 write.

² Coreutils도 있습니다FAQ 포털,archive.org 링크, FSF가 안정적인 인프라를 영원히 운영할 수 있다고 믿지 않기 때문입니다.

답변2

재귀 경로에서 소프트 링크를 순회할 수 있다는 점을 고려하세요.

시도해 보는 것이 좋습니다:

 chown -L -R me:me pathToSecondWeirdDirectory
 

find통과하는 심볼릭 링크는 다음 명령 으로 삭제할 수 있습니다.

 find -L <target dir1> <target dir2> ... -delete

관련 정보