I tried removing the '.' directory. I thought I could just delete my working directory without having to go into a parent directory.
The point of my question is to look for some insight into how the linux system works to delete files.
I tried removing the '.' directory. I thought I could just delete my working directory without having to go into a parent directory.
The point of my question is to look for some insight into how the linux system works to delete files.
Removing the current directory does not affect the file system integrity or its logical organization. Preventing .
removal is done to follow the POSIX standard which states in the rmdir(2)
manual page:
If the path argument refers to a path whose final component is either dot or dot-dot, rmdir() shall fail.
One rationale can be found in the rm
manual page:
The rm utility is forbidden to remove the names dot and dot-dot in order to avoid the consequences of inadvertently doing something like:
rm -r .*
On the other hand, explicitly removing the current directory (i.e. by stating its full or relative path) is an allowed operation under Unix, at least since SVR3 as it was forbidden with Unix version 7 until SVR2. This is very similar to what happens when you remove a file that is actively being read or written to. Processes accessing the delete file continue their read and write operations just like if nothing happened. After you have removed a process current directory, this directory is no more accessible though its path but its inode stay present on the file system until the process dies or change its own directory.
Note that the process won't be able to use a path relative to its current directory to change its cwd (e.g. cd ..
) because there is no more a ..
entry in its current directory.
When someone type rmdir .
, they likely expect the current directory entry to be removed but when a directory is removed (using its path), three directory entries are actually removed, .
, ..
, and the directory itself.
Removing only .
and not this directory's directory entry would create a non compliant directory but as already stated, it is forbidden by the standard.
As @Emmanuel rightly pointed out, there is a second reason why removing .
is not allowed. There is at least one POSIX compliant OS (Mac OS X with HFS+) that, with strong restrictions, supports creating hardlinks to existing directories. In such case, there is no clear way from inside the directory to know which hardlink is the one expected to be removed.
..
link to it. This is the unique case of link count > 2
for the overwhelming majority of OSes and file systems so "some file systems and/or operating systems" is an understatement. The only non historical known exception is Mac OS X with HFS+ which add restrictions about who and what can be done though. Granted the POSIX comment is directed to this oddity. See http://unix.stackexchange.com/questions/22394/why-are-hard-links-to-directories-not-allowed-in-unix-linux
– jlliagre
Jun 13 '16 at 20:27
rm -r .*
before and it blew away everything under the parent directory recursively... That was more than a decade or two ago but it's nice to know rm
no longer allows this.
– antak
Jun 14 '16 at 00:59
It's done like that for integrity since you are currently inside that directory and the .
is only a self-reference.
You need to either go in its parent or call rmdir
with its path, which can be done with:
rmdir `pwd`
If you often need that, you can set an alias to it like:
alias rmc='rmdir `pwd`'
.. which could be called as rmc
alone to remove current directory.
rmdir .
command compromise file system integrity in a way that rmdir $(pwd)
or rmdir "$PWD"
does not?
– G-Man Says 'Reinstate Monica'
Jun 13 '16 at 07:08
rm *
and similar variant (think shell history) 2. The question is about "why", not about "how". 3. The statement about integrity is false.
– Franklin Piat
Jun 13 '16 at 12:13
rm *
, and what do you mean by shell history? 2. The answer addressed the why part, 3. Care to elaborate?
– JBentley
Jun 13 '16 at 13:18
rm *
since I don't know either where that came from, but by far most of this answer is about the why, the how is only a minor note. That by itself wouldn't necessary be a problem, but I agree with Franklin Piat that that little how part there is looks pretty clearly wrong, there is nothing in this answer that supports the idea that the rationale is anything other than what's in the official rationale, quoted in jlliagre's answer.
– hvd
Jun 13 '16 at 17:51
rm *
. I guess the remark about shell history is a caution that you might accidentally (re-)execute a command from history, in a different context, with disastrous results. However, by this line of thinking, you should never use commands that are potentially harmful (or you should disable shell history). … (Cont’d)
– Scott - Слава Україні
Jun 13 '16 at 17:55
rmdir $(pwd)
, pwd
figures out a logical name for the current directory, for instance /foo/bar/baz
, and then rmdir
, seeing that path, removes the baz
entry from the /foo/bar
directory, provided the conditions are met. This makes sense. The command rmdir .
, on the other hand, is an instruction to remove the .
entry from the current directory, which is neither allowed (it would violate the constraint that every directory has a .
entry pointing to itself) nor useful (it wouldn't remove the link you wanted removed).
– hobbs
Jun 14 '16 at 05:02
rm .
andrmdir .
do not work, but why they are specified as not working, which is independent of the physical existence of a hard link. – JdeBP Jun 13 '16 at 06:45rm -rf .*
only to find this including not only.
but also..
, and then../..
, and then… – gerrit Jun 13 '16 at 09:42rmdir .
wouldn't remove the working directory, because the link to it in the parent would still exist. It would just remove the directory's link to itself. – Barmar Jun 15 '16 at 17:58