-wx
"Permissions"라는 폴더 folder1
와 그 안에 folder2
" rwx
Permissions" 라는 다른 폴더 가 있습니다 .
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
... 디렉토리가 비어 있지 않기 때문에 실패했습니다. 이제 이것이 읽기 권한이 없음에도 불구하고 디렉터리를 완전히 삭제하려고 시도한다는 사실이 예상치 못한 동작이라고 생각합니다.