"rm -r"로 폴더를 삭제할 수 없는 이유는 무엇입니까?

"rm -r"로 폴더를 삭제할 수 없는 이유는 무엇입니까?

-wx"Permissions"라는 폴더 folder1와 그 안에 folder2" rwxPermissions" 라는 다른 폴더 가 있습니다 .

folder1다음 명령을 사용하여 삭제를 시도했습니다 .

rm -r folder1

하지만 다음과 같은 오류가 발생합니다.

rm: cannot remove 'folder1': Permission denied

이 오류가 발생하는 이유는 해당 콘텐츠를 삭제할 수 있으려면 프로그램이 rm먼저 콘텐츠 folder1(파일과 폴더의 이름을 가져와야 함 )를 가져와야 하기 때문이라고 생각합니다 (파일을 삭제할 수 없기 때문에). folder1또는 이름을 모르는 폴더) 그러면 rm프로그램이 folder1자체적으로 삭제될 수 있습니다.

하지만 folder1권한이 없기 read때문에 rm프로그램은 내용을 가져올 수 없으므로 내용을 삭제할 수 없고, 내용을 삭제할 수 없기 때문에 삭제할 수도 없습니다.

내가 맞나요?

답변1

나는 당신의 분석이 정확하다고 생각합니다. 디렉토리가 비어 있지 않기 때문에 디렉토리를 삭제할 수 없으며 내용을 볼 수 없기 때문에 비울 수 없습니다.

방금 이것을 시도했습니다.

$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$ 

내가 "당신"이라고 쓴다면 당신이 실행할 수 있는 모든 프로그램을 의미합니다. 명령 은 rm -r먼저 이것이 folder1디렉터리임을 확인하고 내용을 검색하여 비우려고 시도하지만 읽기 권한이 부족하여 실패하고 삭제를 시도하지만 비어 있지 않기 때문에 실패합니다. "권한이 거부되었습니다"는 오해의 소지가 있습니다. "디렉토리가 비어 있지 않습니다"( rmdir보고된 대로)가 더 적절하다고 생각합니다 . )

답변2

삭제가 이루어지려면 시스템이 콘텐츠를 읽고 삭제해야 할 내용을 식별할 수 있어야 합니다.

나는 당신이 시도하는 것을 시뮬레이션해 보았습니다.

[vagrant@desktop1 ~]$ sudo rm -rf folder1/ && mkdir -pv folder1/folder2 && sudo chmod 333 -v folder1/ && sudo chmod 777 -v folder1/folder2
mkdir: created directory 'folder1'
mkdir: created directory 'folder1/folder2'
mode of 'folder1/' changed from 0775 (rwxrwxr-x) to 0333 (-wx-wx-wx)
mode of 'folder1/folder2' changed from 0775 (rwxrwxr-x) to 0777 (rwxrwxrwx)
[vagrant@desktop1 ~]$ ls -lh
total 0
d-wx-wx-wx. 3 vagrant vagrant 21 Feb 24 10:40 folder1
[vagrant@desktop1 ~]$ 

읽기 권한 없이 삭제하려고 하면 실패합니다.

[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$ 

두 번의 시도에서 차이점은 디렉터리 내용을 읽을 수 없다는 것입니다(getdents).

newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 EACCES (Permission denied)
geteuid()                               = 1000
newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "folder1/", W_OK)   = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 EACCES (Permission denied)
newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0

읽기 권한이 있는 경우:

newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0777, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFDIR|0777, st_size=21, ...}) = 0
fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
getdents(3, /* 3 entries */, 32768)     = 80
close(3)                                = 0
geteuid()                               = 1000

요약하자면, 디렉터리를 소유하고 실행 비트가 있는 경우에도 해당 내용을 보고 폴더를 삭제할 수 있으려면 읽기 권한이 필요합니다. 하지만 파일의 경우에는 그렇지 않습니다.

답변3

글쎄, 나는 ttaran7의 답변에 대해 언급할 만큼 충분한 평판을 갖고 있지 않으므로 필수 답변인 것 같습니다. 내 평판이 낮기 때문에 내 찬성 투표도 공개적으로 표시되지 않습니다. 이 답변에는 추측뿐만 아니라 실제로 시스템 호출 추적이 포함되어 있기 때문에 이에 투표했습니다.

OP의 질문에 대답하려면: 예, 귀하의 추론이 정확합니다. 디렉토리를 읽을 수 없어 차단되었습니다.

나는 동일한 추론을 의심하기 때문에 그들(ttaran7)이 수행한 것과 유사한 추적을 수행했습니다. rm디렉토리를 읽을 수 없기 때문에 호출이 실패하고 디렉토리가 비어 있다고 불평할 기회가 없이 끝이 될 것입니다. 내가 얻은 추적을 다시 살펴본 후 제공된 파일 이름의 링크를 해제하려고 시스템 호출이 수행되었음을 확인했습니다.

newfstatat(AT_FDCWD, "folder1", {st_mode=S_IFDIR|0311, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "folder1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = -1 EACCES (Permission denied)
unlinkat(AT_FDCWD, "folder1", AT_REMOVEDIR) = -1 ENOTEMPTY (Directory not empty)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2995, ...}) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2995
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale/en_AU/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)
openat(AT_FDCWD, "/usr/share/locale-langpack/en_AU/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=45256, ...}) = 0
mmap(NULL, 45256, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25ca000
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale- langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=578, ...}) = 0
mmap(NULL, 578, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25c9000
close(3)                                = 0
write(2, "rm: ", 4rm: )                     = 4
write(2, "cannot remove 'folder1'", 23cannot remove 'folder1') = 23
openat(AT_FDCWD, "/usr/share/locale/en_AU/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)
openat(AT_FDCWD, "/usr/share/locale-langpack/en_AU/LC_MESSAGES/libc.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2893, ...}) = 0
mmap(NULL, 2893, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25c8000
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": Permission denied", 19: Permission denied)     = 19
write(2, "\n", 1
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exitgroup(1)

네 번째 줄을 보십시오. unlinkat... 디렉토리가 비어 있지 않기 때문에 실패했습니다. 이제 이것이 읽기 권한이 없음에도 불구하고 디렉터리를 완전히 삭제하려고 시도한다는 사실이 예상치 못한 동작이라고 생각합니다.

관련 정보