-2

I am new to Linux. When I make a file as read only I am still able to delete that file. I read on the net that deleting a file depends upon the permissions of the folder in which it lies.

To make things clear let's say I have a directory test(with all permissions) in which I have a read only file 'abc.txt'. Even if this file is read only I can easily delete it.

Now consider the case where I have a subdirectory named 'sub' under test. This directory is read only. When I want to delete this subdirectory it throws an error saying that can't delete this directory.

In linux a directory is also treated as a file. But the behaviour differs for read only files vs read only directories.

What's the reason for this?

closed as unclear what you're asking by muru, Jeff Schaller, Christopher, G-Man, slm Apr 24 '18 at 4:08

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    Have you tried deleting a directory and file that lives in a read-only directory? – Kusalananda Apr 21 '18 at 16:07
  • 1
    Even with the edit, I cannot understand your question and reproduce your claim. My guess is that you try to rmdir a non-empty directory – Basile Starynkevitch Apr 24 '18 at 11:17
  • 2
    What are the exact commands you enter and their output? – Jeff Schaller Apr 24 '18 at 11:20
  • 1
    Please try to put useful information in your question. What command are you using ? how are you using it ? to whom the file belong to ? answer those question and I might vote reopen – Kiwy Apr 24 '18 at 11:54
  • 1
    The fact that your directory was non-empty should be written in your question, not as a comment – Basile Starynkevitch Apr 24 '18 at 12:18
4

Because Unix was defined that way, and POSIX requires that behavior. And Linux tries to be Unix & POSIX compliant.

You might have some misconception about what files are (caveat, there are not exactly the same on Unix and on Windows). BTW, they matter for many system calls (listed in syscalls(2)), with several system calls giving a file descriptor from a file path (see also path_resolution(7)). In contrast to some other OSes, a file (on Linux or Unix or POSIX systems) has not only one name (or path): some files have no names, others have several ones; indeed most files have one name.

Remember that files are an abstraction provided to user-space (and applications -including utility programs- running in processes) by the operating system kernel. And system calls are the only way for programs (and processes running them) to interact with the kernel.

Your disk does not know about files (but your OS does). A disk contains simply blocks of bytes. It is your OS which understands them as files

A file is (on Unix & Linux) an inode. See also inode(7). The inode contains meta-data about that file (which you could query with stat(2), fstat etc...) -including type, creation time, permissions, ownership, size, etc...- and contains (or more often points to) the file data (a sequence of bytes).

But deleting a read only directory poses no problem.

A directory is a special kind of file (there are other kinds of files than plain files and directories, e.g. fifo(7)-s, symlink(7)-s, etc). It contains a dictionary mapping strings to inodes. How that happens is specific to every file system type. Use opendir(3) (and later closedir) and readdir(3) to read it.

.... permissions of of the folder in which it lies...

Misconception. Folders do not exit on Linux (they are a GUI artefact sometimes displayed by your desktop environment), you probably are talking of directories. File systems contains various kind of files (including directories and symbolic links).

A given inode can appear in several directories (you might say that a file could have several paths, then they all have the same "power" and similar "role"). Use the link(2) system call -perhaps via the ln(1) command- for adding some additional path to a file. Use the unlink(2) system call for removing a path to a file. In some cases, an inode can exist without appearing in any directory. A common case (used for implementing temporary files) is when you create a file -e.g. using creat(2) or open then unlink (or remove(3)) that file just after (e.g. in the same process, but perhaps not).

When an inode becomes unreachable (because there is no open file descriptor to it, and because it is no more mentioned in some directory) the kernel removes that inode (and the data blocks related to it).

When you "remove" a file (e.g. using the rm(1) utility), the /bin/rm program (and the process running that command) is just using unlink (and you are writing into a directory containing some mapping between names and inodes). If nothing more "points to" that inode, indeed it gets removed. Since the kernel is writing into a directory, it requires your process to have write permission for that. See also credentials(7).

A directory needs mkdir(2) to be made, and rmdir(2) to be removed (from its parent): if you use unlink(2) to remove it, that would fail with EISDIR. But rmdir(2) requires the directory to be empty (because the kernel requires the file hierarchy to be a direct acyclic graph, and circular references are forbidden, by some kind of reference counting). Both mkdir and rmdir syscalls handle the magic  . and .. entries of directories.

But deleting a read only directory poses no problem. Why this thing does not depend on the parent directory?

It does in general (but sticky bit on directories has some specific meaning).

about edited question

In your edited question, you claim (incorrectly, or else some important detail is missing):

Now consider the case where I have a subdirectory named sub under test. This directory is read only. When I want to delete this subdirectory it throws an error saying that can't delete this directory.

I cannot reproduce your claim (please provide some MCVE). For readability, I am considering directories testdir and subdir instead of your names (but that does not change anything; however your test is confusable with test(1))

 % /bin/mkdir testdir
 % /bin/mkdir testdir/subdir
 % /bin/ls -la testdir
total 12
drwxr-xr-x 3 basile basile 4096 Apr 24 13:09 .
drwxr-xr-x 6 basile basile 4096 Apr 24 13:08 ..
drwxr-xr-x 2 basile basile 4096 Apr 24 13:09 subdir
 % /bin/chmod a-w testdir/subdir
 % /bin/ls -la testdir          
total 12
drwxr-xr-x 3 basile basile 4096 Apr 24 13:09 .
drwxr-xr-x 6 basile basile 4096 Apr 24 13:08 ..
dr-xr-xr-x 2 basile basile 4096 Apr 24 13:09 subdir
 % /bin/rmdir testdir/subdir  
 % /bin/ls -la testdir      
total 8
drwxr-xr-x 2 basile basile 4096 Apr 24 13:14 .
drwxr-xr-x 6 basile basile 4096 Apr 24 13:08 ..

Remember that rmdir(1) (it uses the rmdir(2) system call) require the removed directory to be empty, and some files (whose name starts with a dot) could be "hidden" by your shell or by ls. List all files of the removed directory with ls -a


You might read Operating Systems: Three Easy Pieces

  • 1
    Note that removing a directory implies unlinking the . and .. entries in it prior to unlinking the directory from its parent, so means modifying the directory first. Historically, that was done in user space. But rmdir was setuid root, so you still didn't need write permission to the directory, rmdir only checked that you had write access to the parent. Nowadays, that unlinking of . and .. (for FSs that do have real directory entries for them) is done in the kernel as part of the rmdir() system call. – Stéphane Chazelas Apr 23 '18 at 6:56
  • @Basile sorry my question was not formulated in the right way. I have edited it to make it more clear. Please have a look. – Kishan Kumar Apr 24 '18 at 10:48
  • 1
    TL,DR: To remove a non-empty subdirectory (as in the question) requires one to empty the subdirectory first, which requires modifying the subdirectory and hence the w permission. That's why a non-empty read-only directory cannot be removed with rm -rf. – Weijun Zhou Dec 12 '18 at 2:07
3

No, you cannot remove a directory if its parent directory is read-only. Try it for yourself:

$ cd /tmp
$ mkdir -p /tmp/readonly1/readonly2
$ chmod 555 /tmp/readonly1/readonly2 /tmp/readonly1   # dr-xr-xr-x
$ rmdir /tmp/readonly1/readonly2
rmdir: failed to remove '/tmp/readonly1/readonly2': Permission denied

Removing with force won't help either:

$ rm -rf /tmp/readonly1/readonly2
rm: cannot remove '/tmp/readonly1/readonly2': Permission denied
$ rm -rf /tmp/readonly1
rm: cannot remove '/tmp/readonly1/readonly2': Permission denied
$ chmod 755 /tmp/readonly1/readonly2  # drwxr-xr-x
$ rm -rf /tmp/readonly1
rm: cannot remove '/tmp/readonly1/readonly2': Permission denied

But as soon as you make the readonly1 directory writeable, you can remove its sub-directory readonly2:

$ chmod 555 /tmp/readonly1/readonly2  # dr-xr-xr-x
$ chmod 755 /tmp/readonly1            # drwxr-xr-x
$ rmdir /tmp/readonly1/readonly2
$ rmdir /tmp/readonly1        #... or just rm -rf /tmp/readonly1 all at once
$ ls /tmp/readonly1
ls: cannot access '/tmp/readonly1': No such file or directory
  • That does not explain why a read-only file can be removed. – Basile Starynkevitch Apr 21 '18 at 14:54
  • 2
    And that is not what the original poster asked, if you read more than the title of the question. – telcoM Apr 21 '18 at 15:18
  • The original poster's question does seem a bit confused, so it's probably a good thing you covered that part. Let the votes fall as they may. – telcoM Apr 21 '18 at 15:25
  • @telcoM U didn't answer my question. Whatever u said I already knew that. – Kishan Kumar Apr 22 '18 at 15:25
  • 1
    Well, then I misinterpreted your question, sorry about that. I hope Basile's answer was more useful to you then. – telcoM Apr 23 '18 at 5:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.