Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

While toying with the file system, I tried the following:

mkdir a
cd a
rmdir .

Which results in:

rmdir: failed to remove ‘.’: Invalid argument

Ok, Mr. rmdir, let me outsmart you:

rmdir ../a

...Ok.

What? No error this time?

My terminal still says I'm in directory a, yet ls -a lists nothing (neither . nor ..), but ls .. and pwd still work as expected.

Am I like one of those cartoon characters who cut its own branch but still hasn't fallen?

If I try

mkdir ../a

It creates a directory a, but this is still not the directory I am standing on (ls -a . and ls -a ../a show different results).

If I try to create a file with touch b it replies:

touch: cannot touch ‘b’: No such file or directory

But touch . works.

Finally, as soon as I leave my directory, it disappears and I cannot return to it.

Edit: Could someone please explain what is happening here? Is there a name for this situation? Is this an issue between the filesystem and Bash, or some special hard-coded behavior in Bash?

share|improve this question
    
Can you reword this so the question you're asking is more obvious? –  Rich Homolka Jan 29 at 19:35
1  
When you CD into a directory bash grabs it by the inode, when you remove it and recreate it by other name you have created a different inode. If you recreate the dir with the same inode bash won't notice the difference. I will go further on the rest when I get home, but no doubt someone will write a 4 page essay by then :D –  Yarek T Jan 29 at 20:00

2 Answers 2

up vote 6 down vote accepted

This isn't anything to do with bash.

It's standard Unix behaviour, these many decades past. It's standard behaviour of the kernel, and nothing to do with shells.

The important thing to remember is that files and directories don't have to have names. A file or directory remains in existence as long as it (a) has a non-zero link count, (b) is referenced by an open file descriptor, or (c) is the working directory of a process. (There are a couple of other conditions that can prevent a file or a directory from disappearing into nonexistence, but they aren't relevant to your question here.)

With files, you should be well used to the idea of creating an unnamed temporary file, that is automatically cleaned up when the last open file descriptor to it is closed, by opening a file and then unlinking it so that its link count drops to zero. (This is glossing over a lot of security-related details that aren't relevant to this question.)

You should also be well used to the idea that you can unlink a file that some process has an open file descriptor for, create a new file by the same name, and they will be two different files.

You've simply just done the same things with a directory. You emptied the directory and unlinked it, but it continued to exist until it was no longer referenced by an open file descriptor and was no longer the working directory of any processes. When you created a new directory by the same name that you had unlinked, you had two different directories.

Note that the SUS allows rmdir ../a to fail if the directory named is the current directory of any process. (This isn't to give POSIX APIs layered on top of Windows NT a loophole, as some might think. QNX fails the call in this case, too, for example.) You're obviously running an operating system that (in the absence of considerations like root directories and mount points, which your question doesn't involve) chooses the other allowed alternative, which is to unlink the directory, remove the . and .. entries, and prohibit making new entries.

Further reading

  • "rmdir". The Open Group Base Specifications. IEEE Std 1003.1. Issue 7. 2013.
  • "rmdir". QNX Neutrino Realtime Operating System Library Reference. QNX Developer Support.
share|improve this answer

As a complement to JdeBP's excellent answer, you can confirm that this is indeed what's going on by checking the inode of the directory in question:

$ mkdir ~/foo
$ ls -di ~/foo
16654483 /home/terdon/foo
$ cd ~/foo
$ rmdir ../foo/
$ ls -di ../foo
ls: cannot access ../foo: No such file or directory
$ mkdir ../foo
$ ls -di ../foo
16654484 ../foo

Note that the inode number has changed, this is a new directory with no connection to the old one apart from happening to have the same name.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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