$ mv . ../general/ mv: cannot move `.' to `../general/.': Device or resource busy
Does it mean that the current directory is a busy device or resource, and can't be moved away? Why is it?
It is not possible to move a dot
.. The dot is not the same as current directory name. You can think about
. as a pointer to the directory, but not the directory itself, therefore,
$ pwd && echo $PWD && realpath . /home/jimmij/tmp /home/jimmij/tmp /home/jimmij/tmp $ mkdir tmp1 tmp2 $ mv tmp1/. tmp2/ mv: cannot move ‘tmp1/.’ to ‘tmp2/.’: Device or resource busy
doesn't work, but
cd tmp1 mv ../tmp1 ../tmp2
works fine, so actually you can move current directory, although some commands can be confused after this operation:
$ pwd && echo $PWD && realpath . /home/jimmij/tmp/tmp1 /home/jimmij/tmp/tmp1 /home/jimmij/tmp/tmp2/tmp1 $ cd . $ pwd && echo $PWD && realpath . /home/jimmij/tmp/tmp2/tmp1 /home/jimmij/tmp/tmp2/tmp1 /home/jimmij/tmp/tmp2/tmp1
Similar story with
.., i.e. parent directory.
In other words each directory must contain at least two elements:
... You cannot move or delete them.
The reason you're getting the message:
mv: cannot move
.' to../general/.': Device or resource busy
is due to how the
.. work in addition to
mv. When you move something in Unix, the
mv command attempts to unlink everything that references the inode of the item that you're attempting to move. In this case that would be the inode of whatever the directory is that
. is referencing.
.. are linking to inodes and are in a sense special. You can read about their history here in the U&L Q&A titled: Why does a new directory have a hard link count of 2 before anything is added to it? If you've ever looked at a newly created directory, you'll notice that it always starts with a linked count of 2. The reason is due to the existence of the
$ mkdir adir $ ls -l | grep adir drwxrwxr-x. 2 saml saml 4096 Oct 5 08:02 adir $ ls -la adir/ total 8 drwxrwxr-x. 2 saml saml 4096 Oct 5 08:02 . drwxrwxr-x. 3 saml saml 4096 Oct 5 08:02 ..
NOTE: Reference for
ls output if you're unclear is here in this U&L Q&A titled: What do the fields in ls -al output mean?
So they aren't names of actual directories, but are "symbols/links" that are linking to them. Therefore they meed to be unlinked prior to being able to
Well since your command is using the
., it cannot be unlinked by the
mv command, hence the msg: "Device or resource busy".
Linux forbids renaming any path that ends in the component
.., returning the error EBUSY; the following will also fail:
$ mkdir a a/aa $ mv a/aa/.. b mv: cannot move ‘a/aa/..’ to ‘b/..’: Device or resource busy
The code for this is in
namei.c::renameat. The last component of the pathname when passed to various functions needs to be of type
FreeBSD returns the error EINVAL in each of these cases.
We can only guess as to why there is this restriction.
The rename() function shall fail if:
[EBUSY] The directory named by old or new is currently in use by the system or another process, and the implementation considers this an error.
One could consider
. to currently be in use by the process. But note that Linux allows the following, so a directory merely being in use by some process is not sufficient for
rename to fail:
$ mkdir /tmp/t $ cd /tmp/t $ mv /tmp/t /tmp/t1 $ /bin/pwd /tmp/t1
The reason for forbidding the renaming of
.. is probably "leads to less user confusion".
.is typically a hard link to the directory's entry in its parent, and is somewhat special in that a process can always open
.to access its current working directory. Being able to rename it would be counterproductive.
..is typically a hard link to the directory's parent, and is somewhat special in that a process opening
..will get the parent directory (or the directory itself, if it's a mount point). Being able to rename it would be counterproductive.
Linux also forbids
rmdir of a path whose last component is
.. (ENOTEMPTY) or
. (EINVAL). FreeBSD returns the error EINVAL for each of these.
The POSIX standard for rmdir has this:
The rmdir() function shall fail if:
[EINVAL] The path argument contains a last component that is dot.