Why is “rm -r” unable to delete this folder?
I have a folder with -wx
permissions called folder1
and another folder inside it called folder2
with rwx
permissions.
I tried to delete folder1
using this command:
rm -r folder1
But I got the following error:
rm: cannot remove 'folder1': Permission denied
The reason I think I got this error is because the rm
program needs to first get the content of folder1
(get the names of the files and folders inside folder1
that is) in order to be able to delete that content (because you can't delete a file or folder without knowing its name I think), and then the rm
program can delete folder1
itself.
But since folder1
doesn't have the read
permission, then the rm
program can't get its content, and hence it can't delete its content, and since it can't delete its content, then it can't delete it.
Am I correct?
linux permissions rm
add a comment |
I have a folder with -wx
permissions called folder1
and another folder inside it called folder2
with rwx
permissions.
I tried to delete folder1
using this command:
rm -r folder1
But I got the following error:
rm: cannot remove 'folder1': Permission denied
The reason I think I got this error is because the rm
program needs to first get the content of folder1
(get the names of the files and folders inside folder1
that is) in order to be able to delete that content (because you can't delete a file or folder without knowing its name I think), and then the rm
program can delete folder1
itself.
But since folder1
doesn't have the read
permission, then the rm
program can't get its content, and hence it can't delete its content, and since it can't delete its content, then it can't delete it.
Am I correct?
linux permissions rm
1
Do "ls -l" and tell us what the permissions of the DIRECTORY are.
– jamesqf
Feb 25 at 0:11
add a comment |
I have a folder with -wx
permissions called folder1
and another folder inside it called folder2
with rwx
permissions.
I tried to delete folder1
using this command:
rm -r folder1
But I got the following error:
rm: cannot remove 'folder1': Permission denied
The reason I think I got this error is because the rm
program needs to first get the content of folder1
(get the names of the files and folders inside folder1
that is) in order to be able to delete that content (because you can't delete a file or folder without knowing its name I think), and then the rm
program can delete folder1
itself.
But since folder1
doesn't have the read
permission, then the rm
program can't get its content, and hence it can't delete its content, and since it can't delete its content, then it can't delete it.
Am I correct?
linux permissions rm
I have a folder with -wx
permissions called folder1
and another folder inside it called folder2
with rwx
permissions.
I tried to delete folder1
using this command:
rm -r folder1
But I got the following error:
rm: cannot remove 'folder1': Permission denied
The reason I think I got this error is because the rm
program needs to first get the content of folder1
(get the names of the files and folders inside folder1
that is) in order to be able to delete that content (because you can't delete a file or folder without knowing its name I think), and then the rm
program can delete folder1
itself.
But since folder1
doesn't have the read
permission, then the rm
program can't get its content, and hence it can't delete its content, and since it can't delete its content, then it can't delete it.
Am I correct?
linux permissions rm
linux permissions rm
edited Feb 24 at 20:54
psmears
44528
44528
asked Feb 24 at 10:18
JohnJohn
23119
23119
1
Do "ls -l" and tell us what the permissions of the DIRECTORY are.
– jamesqf
Feb 25 at 0:11
add a comment |
1
Do "ls -l" and tell us what the permissions of the DIRECTORY are.
– jamesqf
Feb 25 at 0:11
1
1
Do "ls -l" and tell us what the permissions of the DIRECTORY are.
– jamesqf
Feb 25 at 0:11
Do "ls -l" and tell us what the permissions of the DIRECTORY are.
– jamesqf
Feb 25 at 0:11
add a comment |
3 Answers
3
active
oldest
votes
I think your analysis is correct: you cannot delete the directory since its non-empty, and you cannot empty it since you cannot see its contents.
I just gave it a try:
$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$
When I wrote “you”, I meant any program you may run. Your rm -r
command first sees that folder1
is a directory, so it tries to discover its contents to empty it, but fails for missing read permission, then it tries to delete it but fails because it’s non-empty. The “Permission denied” is misleading; I think “Directory not empty” (like rmdir
reports) would be more appropriate.)
4
It can't reportDirectory not empty
in this case since it would not know it was empty or not. You would still get the same error when trying to delete an empty directory that you don't have read permissions on. (Also, please disregard my previous comment, I didn't have my thinking cap on).
– Kusalananda
Feb 24 at 10:44
1
@Kusalananda That sounds sane, butrmdir
is able to report “Directory not empty”. And if you read my test, you’ll see that it accepts to remove thefolder1
directory, with no read permission, once I have emptied it.
– user2233709
Feb 24 at 11:24
1
Your test shows an interesting difference between our systems. I get aPermission denied
when trying torm -r folder1
when it's empty. I'm on OpenBSD, not Linux.
– Kusalananda
Feb 24 at 11:47
@Kusalananda That’s interesting. I would have thought that this behavior was specified by the Single Unix Specification, so that Linux and {Free,Net,Open}BSD would behave identically. (For the record, I am using Debian Stretch 9.8 with a linux 4.9.144-3 x86_64 kernel.)
– user2233709
Feb 24 at 12:24
Hmm... The only thing that POSIX says is that if the operand is a directory and-r
is used, each directory entry (except for.
and..
) should be removed as if they were a file operand ofrm -r
. It appears as if GNUrm
simply does armdir()
on the directory if it's not readable, because it will have no way to get the contents of it.
– Kusalananda
Feb 24 at 12:33
|
show 3 more comments
For deletion to occur the system must be able to read the contents and identify what has to be deleted.
I've tried simulating what you are attempting :
[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 ~]$
If we try deleting without read permissions it fails:
[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$
In an strace for the two attempts the difference is that the directory contents cannot be read (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
With read permissions:
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
To conclude even if you own a directory and it has the executable bit, you still need read permissions so that you may see its contents and delete the folder. It's not the same for a file though.
add a comment |
Well, I don't have enough reputation to comment on the answer by ttaran7, so it looks like an answer it will have to be. My up-vote isn't publicly visible either, due to low reputation. I up voted that answer for actually including a system call trace, rather than just speculation.
To answer the OP's question: Yes, your reasoning was correct: You get blocked at the failure to read the directory
I ran a similar trace to what they (ttaran7) had done because I suspected the same reasoning: The rm
call would fail upon failing to read the directory and that would be the end of that, no chance to complain about the directory being empty. Upon taking a second look at the trace that I took, I noticed that a system call was made to attempt to unlink the provided filename anyway:
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)
Look at the 4th line: unlinkat
... which fails because the directory is NOT empty. Now that is what I would consider unexpected behaviour, the fact it tries to delete the directory at all, despite not having read permissions that is.
New contributor
Your conclusion is wrong (mistyped?): ENOTEMPTY means the the directory is NOT empty.
– guntbert
Feb 26 at 21:19
Ah, you're right, I'll correct that when I get to a real keyboard. Thanks.
– ojklan
Feb 26 at 21:24
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502659%2fwhy-is-rm-r-unable-to-delete-this-folder%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think your analysis is correct: you cannot delete the directory since its non-empty, and you cannot empty it since you cannot see its contents.
I just gave it a try:
$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$
When I wrote “you”, I meant any program you may run. Your rm -r
command first sees that folder1
is a directory, so it tries to discover its contents to empty it, but fails for missing read permission, then it tries to delete it but fails because it’s non-empty. The “Permission denied” is misleading; I think “Directory not empty” (like rmdir
reports) would be more appropriate.)
4
It can't reportDirectory not empty
in this case since it would not know it was empty or not. You would still get the same error when trying to delete an empty directory that you don't have read permissions on. (Also, please disregard my previous comment, I didn't have my thinking cap on).
– Kusalananda
Feb 24 at 10:44
1
@Kusalananda That sounds sane, butrmdir
is able to report “Directory not empty”. And if you read my test, you’ll see that it accepts to remove thefolder1
directory, with no read permission, once I have emptied it.
– user2233709
Feb 24 at 11:24
1
Your test shows an interesting difference between our systems. I get aPermission denied
when trying torm -r folder1
when it's empty. I'm on OpenBSD, not Linux.
– Kusalananda
Feb 24 at 11:47
@Kusalananda That’s interesting. I would have thought that this behavior was specified by the Single Unix Specification, so that Linux and {Free,Net,Open}BSD would behave identically. (For the record, I am using Debian Stretch 9.8 with a linux 4.9.144-3 x86_64 kernel.)
– user2233709
Feb 24 at 12:24
Hmm... The only thing that POSIX says is that if the operand is a directory and-r
is used, each directory entry (except for.
and..
) should be removed as if they were a file operand ofrm -r
. It appears as if GNUrm
simply does armdir()
on the directory if it's not readable, because it will have no way to get the contents of it.
– Kusalananda
Feb 24 at 12:33
|
show 3 more comments
I think your analysis is correct: you cannot delete the directory since its non-empty, and you cannot empty it since you cannot see its contents.
I just gave it a try:
$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$
When I wrote “you”, I meant any program you may run. Your rm -r
command first sees that folder1
is a directory, so it tries to discover its contents to empty it, but fails for missing read permission, then it tries to delete it but fails because it’s non-empty. The “Permission denied” is misleading; I think “Directory not empty” (like rmdir
reports) would be more appropriate.)
4
It can't reportDirectory not empty
in this case since it would not know it was empty or not. You would still get the same error when trying to delete an empty directory that you don't have read permissions on. (Also, please disregard my previous comment, I didn't have my thinking cap on).
– Kusalananda
Feb 24 at 10:44
1
@Kusalananda That sounds sane, butrmdir
is able to report “Directory not empty”. And if you read my test, you’ll see that it accepts to remove thefolder1
directory, with no read permission, once I have emptied it.
– user2233709
Feb 24 at 11:24
1
Your test shows an interesting difference between our systems. I get aPermission denied
when trying torm -r folder1
when it's empty. I'm on OpenBSD, not Linux.
– Kusalananda
Feb 24 at 11:47
@Kusalananda That’s interesting. I would have thought that this behavior was specified by the Single Unix Specification, so that Linux and {Free,Net,Open}BSD would behave identically. (For the record, I am using Debian Stretch 9.8 with a linux 4.9.144-3 x86_64 kernel.)
– user2233709
Feb 24 at 12:24
Hmm... The only thing that POSIX says is that if the operand is a directory and-r
is used, each directory entry (except for.
and..
) should be removed as if they were a file operand ofrm -r
. It appears as if GNUrm
simply does armdir()
on the directory if it's not readable, because it will have no way to get the contents of it.
– Kusalananda
Feb 24 at 12:33
|
show 3 more comments
I think your analysis is correct: you cannot delete the directory since its non-empty, and you cannot empty it since you cannot see its contents.
I just gave it a try:
$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$
When I wrote “you”, I meant any program you may run. Your rm -r
command first sees that folder1
is a directory, so it tries to discover its contents to empty it, but fails for missing read permission, then it tries to delete it but fails because it’s non-empty. The “Permission denied” is misleading; I think “Directory not empty” (like rmdir
reports) would be more appropriate.)
I think your analysis is correct: you cannot delete the directory since its non-empty, and you cannot empty it since you cannot see its contents.
I just gave it a try:
$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$
When I wrote “you”, I meant any program you may run. Your rm -r
command first sees that folder1
is a directory, so it tries to discover its contents to empty it, but fails for missing read permission, then it tries to delete it but fails because it’s non-empty. The “Permission denied” is misleading; I think “Directory not empty” (like rmdir
reports) would be more appropriate.)
edited Feb 25 at 0:20
terdon♦
131k32258437
131k32258437
answered Feb 24 at 10:25
user2233709user2233709
1,098312
1,098312
4
It can't reportDirectory not empty
in this case since it would not know it was empty or not. You would still get the same error when trying to delete an empty directory that you don't have read permissions on. (Also, please disregard my previous comment, I didn't have my thinking cap on).
– Kusalananda
Feb 24 at 10:44
1
@Kusalananda That sounds sane, butrmdir
is able to report “Directory not empty”. And if you read my test, you’ll see that it accepts to remove thefolder1
directory, with no read permission, once I have emptied it.
– user2233709
Feb 24 at 11:24
1
Your test shows an interesting difference between our systems. I get aPermission denied
when trying torm -r folder1
when it's empty. I'm on OpenBSD, not Linux.
– Kusalananda
Feb 24 at 11:47
@Kusalananda That’s interesting. I would have thought that this behavior was specified by the Single Unix Specification, so that Linux and {Free,Net,Open}BSD would behave identically. (For the record, I am using Debian Stretch 9.8 with a linux 4.9.144-3 x86_64 kernel.)
– user2233709
Feb 24 at 12:24
Hmm... The only thing that POSIX says is that if the operand is a directory and-r
is used, each directory entry (except for.
and..
) should be removed as if they were a file operand ofrm -r
. It appears as if GNUrm
simply does armdir()
on the directory if it's not readable, because it will have no way to get the contents of it.
– Kusalananda
Feb 24 at 12:33
|
show 3 more comments
4
It can't reportDirectory not empty
in this case since it would not know it was empty or not. You would still get the same error when trying to delete an empty directory that you don't have read permissions on. (Also, please disregard my previous comment, I didn't have my thinking cap on).
– Kusalananda
Feb 24 at 10:44
1
@Kusalananda That sounds sane, butrmdir
is able to report “Directory not empty”. And if you read my test, you’ll see that it accepts to remove thefolder1
directory, with no read permission, once I have emptied it.
– user2233709
Feb 24 at 11:24
1
Your test shows an interesting difference between our systems. I get aPermission denied
when trying torm -r folder1
when it's empty. I'm on OpenBSD, not Linux.
– Kusalananda
Feb 24 at 11:47
@Kusalananda That’s interesting. I would have thought that this behavior was specified by the Single Unix Specification, so that Linux and {Free,Net,Open}BSD would behave identically. (For the record, I am using Debian Stretch 9.8 with a linux 4.9.144-3 x86_64 kernel.)
– user2233709
Feb 24 at 12:24
Hmm... The only thing that POSIX says is that if the operand is a directory and-r
is used, each directory entry (except for.
and..
) should be removed as if they were a file operand ofrm -r
. It appears as if GNUrm
simply does armdir()
on the directory if it's not readable, because it will have no way to get the contents of it.
– Kusalananda
Feb 24 at 12:33
4
4
It can't report
Directory not empty
in this case since it would not know it was empty or not. You would still get the same error when trying to delete an empty directory that you don't have read permissions on. (Also, please disregard my previous comment, I didn't have my thinking cap on).– Kusalananda
Feb 24 at 10:44
It can't report
Directory not empty
in this case since it would not know it was empty or not. You would still get the same error when trying to delete an empty directory that you don't have read permissions on. (Also, please disregard my previous comment, I didn't have my thinking cap on).– Kusalananda
Feb 24 at 10:44
1
1
@Kusalananda That sounds sane, but
rmdir
is able to report “Directory not empty”. And if you read my test, you’ll see that it accepts to remove the folder1
directory, with no read permission, once I have emptied it.– user2233709
Feb 24 at 11:24
@Kusalananda That sounds sane, but
rmdir
is able to report “Directory not empty”. And if you read my test, you’ll see that it accepts to remove the folder1
directory, with no read permission, once I have emptied it.– user2233709
Feb 24 at 11:24
1
1
Your test shows an interesting difference between our systems. I get a
Permission denied
when trying to rm -r folder1
when it's empty. I'm on OpenBSD, not Linux.– Kusalananda
Feb 24 at 11:47
Your test shows an interesting difference between our systems. I get a
Permission denied
when trying to rm -r folder1
when it's empty. I'm on OpenBSD, not Linux.– Kusalananda
Feb 24 at 11:47
@Kusalananda That’s interesting. I would have thought that this behavior was specified by the Single Unix Specification, so that Linux and {Free,Net,Open}BSD would behave identically. (For the record, I am using Debian Stretch 9.8 with a linux 4.9.144-3 x86_64 kernel.)
– user2233709
Feb 24 at 12:24
@Kusalananda That’s interesting. I would have thought that this behavior was specified by the Single Unix Specification, so that Linux and {Free,Net,Open}BSD would behave identically. (For the record, I am using Debian Stretch 9.8 with a linux 4.9.144-3 x86_64 kernel.)
– user2233709
Feb 24 at 12:24
Hmm... The only thing that POSIX says is that if the operand is a directory and
-r
is used, each directory entry (except for .
and ..
) should be removed as if they were a file operand of rm -r
. It appears as if GNU rm
simply does a rmdir()
on the directory if it's not readable, because it will have no way to get the contents of it.– Kusalananda
Feb 24 at 12:33
Hmm... The only thing that POSIX says is that if the operand is a directory and
-r
is used, each directory entry (except for .
and ..
) should be removed as if they were a file operand of rm -r
. It appears as if GNU rm
simply does a rmdir()
on the directory if it's not readable, because it will have no way to get the contents of it.– Kusalananda
Feb 24 at 12:33
|
show 3 more comments
For deletion to occur the system must be able to read the contents and identify what has to be deleted.
I've tried simulating what you are attempting :
[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 ~]$
If we try deleting without read permissions it fails:
[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$
In an strace for the two attempts the difference is that the directory contents cannot be read (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
With read permissions:
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
To conclude even if you own a directory and it has the executable bit, you still need read permissions so that you may see its contents and delete the folder. It's not the same for a file though.
add a comment |
For deletion to occur the system must be able to read the contents and identify what has to be deleted.
I've tried simulating what you are attempting :
[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 ~]$
If we try deleting without read permissions it fails:
[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$
In an strace for the two attempts the difference is that the directory contents cannot be read (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
With read permissions:
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
To conclude even if you own a directory and it has the executable bit, you still need read permissions so that you may see its contents and delete the folder. It's not the same for a file though.
add a comment |
For deletion to occur the system must be able to read the contents and identify what has to be deleted.
I've tried simulating what you are attempting :
[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 ~]$
If we try deleting without read permissions it fails:
[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$
In an strace for the two attempts the difference is that the directory contents cannot be read (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
With read permissions:
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
To conclude even if you own a directory and it has the executable bit, you still need read permissions so that you may see its contents and delete the folder. It's not the same for a file though.
For deletion to occur the system must be able to read the contents and identify what has to be deleted.
I've tried simulating what you are attempting :
[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 ~]$
If we try deleting without read permissions it fails:
[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$
In an strace for the two attempts the difference is that the directory contents cannot be read (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
With read permissions:
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
To conclude even if you own a directory and it has the executable bit, you still need read permissions so that you may see its contents and delete the folder. It's not the same for a file though.
edited Feb 24 at 21:42
George
1104
1104
answered Feb 24 at 10:48
ttaran7ttaran7
714
714
add a comment |
add a comment |
Well, I don't have enough reputation to comment on the answer by ttaran7, so it looks like an answer it will have to be. My up-vote isn't publicly visible either, due to low reputation. I up voted that answer for actually including a system call trace, rather than just speculation.
To answer the OP's question: Yes, your reasoning was correct: You get blocked at the failure to read the directory
I ran a similar trace to what they (ttaran7) had done because I suspected the same reasoning: The rm
call would fail upon failing to read the directory and that would be the end of that, no chance to complain about the directory being empty. Upon taking a second look at the trace that I took, I noticed that a system call was made to attempt to unlink the provided filename anyway:
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)
Look at the 4th line: unlinkat
... which fails because the directory is NOT empty. Now that is what I would consider unexpected behaviour, the fact it tries to delete the directory at all, despite not having read permissions that is.
New contributor
Your conclusion is wrong (mistyped?): ENOTEMPTY means the the directory is NOT empty.
– guntbert
Feb 26 at 21:19
Ah, you're right, I'll correct that when I get to a real keyboard. Thanks.
– ojklan
Feb 26 at 21:24
add a comment |
Well, I don't have enough reputation to comment on the answer by ttaran7, so it looks like an answer it will have to be. My up-vote isn't publicly visible either, due to low reputation. I up voted that answer for actually including a system call trace, rather than just speculation.
To answer the OP's question: Yes, your reasoning was correct: You get blocked at the failure to read the directory
I ran a similar trace to what they (ttaran7) had done because I suspected the same reasoning: The rm
call would fail upon failing to read the directory and that would be the end of that, no chance to complain about the directory being empty. Upon taking a second look at the trace that I took, I noticed that a system call was made to attempt to unlink the provided filename anyway:
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)
Look at the 4th line: unlinkat
... which fails because the directory is NOT empty. Now that is what I would consider unexpected behaviour, the fact it tries to delete the directory at all, despite not having read permissions that is.
New contributor
Your conclusion is wrong (mistyped?): ENOTEMPTY means the the directory is NOT empty.
– guntbert
Feb 26 at 21:19
Ah, you're right, I'll correct that when I get to a real keyboard. Thanks.
– ojklan
Feb 26 at 21:24
add a comment |
Well, I don't have enough reputation to comment on the answer by ttaran7, so it looks like an answer it will have to be. My up-vote isn't publicly visible either, due to low reputation. I up voted that answer for actually including a system call trace, rather than just speculation.
To answer the OP's question: Yes, your reasoning was correct: You get blocked at the failure to read the directory
I ran a similar trace to what they (ttaran7) had done because I suspected the same reasoning: The rm
call would fail upon failing to read the directory and that would be the end of that, no chance to complain about the directory being empty. Upon taking a second look at the trace that I took, I noticed that a system call was made to attempt to unlink the provided filename anyway:
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)
Look at the 4th line: unlinkat
... which fails because the directory is NOT empty. Now that is what I would consider unexpected behaviour, the fact it tries to delete the directory at all, despite not having read permissions that is.
New contributor
Well, I don't have enough reputation to comment on the answer by ttaran7, so it looks like an answer it will have to be. My up-vote isn't publicly visible either, due to low reputation. I up voted that answer for actually including a system call trace, rather than just speculation.
To answer the OP's question: Yes, your reasoning was correct: You get blocked at the failure to read the directory
I ran a similar trace to what they (ttaran7) had done because I suspected the same reasoning: The rm
call would fail upon failing to read the directory and that would be the end of that, no chance to complain about the directory being empty. Upon taking a second look at the trace that I took, I noticed that a system call was made to attempt to unlink the provided filename anyway:
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)
Look at the 4th line: unlinkat
... which fails because the directory is NOT empty. Now that is what I would consider unexpected behaviour, the fact it tries to delete the directory at all, despite not having read permissions that is.
New contributor
edited Feb 26 at 21:41
New contributor
answered Feb 25 at 8:47
ojklanojklan
12
12
New contributor
New contributor
Your conclusion is wrong (mistyped?): ENOTEMPTY means the the directory is NOT empty.
– guntbert
Feb 26 at 21:19
Ah, you're right, I'll correct that when I get to a real keyboard. Thanks.
– ojklan
Feb 26 at 21:24
add a comment |
Your conclusion is wrong (mistyped?): ENOTEMPTY means the the directory is NOT empty.
– guntbert
Feb 26 at 21:19
Ah, you're right, I'll correct that when I get to a real keyboard. Thanks.
– ojklan
Feb 26 at 21:24
Your conclusion is wrong (mistyped?): ENOTEMPTY means the the directory is NOT empty.
– guntbert
Feb 26 at 21:19
Your conclusion is wrong (mistyped?): ENOTEMPTY means the the directory is NOT empty.
– guntbert
Feb 26 at 21:19
Ah, you're right, I'll correct that when I get to a real keyboard. Thanks.
– ojklan
Feb 26 at 21:24
Ah, you're right, I'll correct that when I get to a real keyboard. Thanks.
– ojklan
Feb 26 at 21:24
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502659%2fwhy-is-rm-r-unable-to-delete-this-folder%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Do "ls -l" and tell us what the permissions of the DIRECTORY are.
– jamesqf
Feb 25 at 0:11