Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

On Linux, I moved a directory to another directory using mv, and in another shell, my working directory happened to be the directory that was moved.

I ran hg pull in that shell, and to my surprise, it ran correctly in the new working directory - without me having to type cd.

How did that work?

share|improve this question
add comment

2 Answers

Moving a file or directory changes the meta-data property that identifies its parent in the file tree, but it doesn't change its actual node id. On the physical disk it's still in the same place, and the filesystem still knows it as the same object. Anywhere the file or directory pointer is open, it is already connected to that object, and a change to the objects meta-data won't affect open processes. Things will only break when you try to to open a new pointer based on the file system path.

By the same token you can move a file that is being written to and the writes will keep going to the new location; because it's actually the same file node, just re-attached to a different place in the file structure. Neither the physical location on the disk nor the node id changes, the file system just updates its internal map of nodes on the disk to paths in the filesystem.

Also of note, this behavior only applies when the moved object stays on the same file system. If you move it from one mount to another the physical location of the node has to change and the object will get deleted from the original file system, leaving dead pointers!

share|improve this answer
    
... and also, if you move a direction on an NFS server, NFS clients may lose it. Depending on the NFS server settings (in particular, subtree_check, see the docs for details) –  derobert Jun 28 '13 at 21:57
add comment

Unix kernels keep track of what directory every process has for a working directory. You can prove this by cd'ing into a mounted volume, and then, as root, doing a umount on the mount point. You'll get some message about how the device is busy.

And clearly, modern shells have the working directory they say they have, otherwise programs that are children of the shell (C, Python or otherwise) wouldn't open the correct file when given a relative path on the command line.

But modern shells (ksh, bash, zsh, maybe others) play games with the working directory. You can prove this by creating a directory tree that has a symbolic link somewhere in the mid-levels:

% mkdir a
% cd a
% mkdir b.orig
% ln -s b.orig b
% mkdir b.orig/c
% cd .. 
% cd a/b/c
% pwd
/home/bediger/a/b/c

That's all with zsh. It follows the symbolic link back up the tree, where, if it were just working it's way up using ".." directories, it would find a/b.orig/c

share|improve this answer
2  
"And clearly, modern shells have the working directory they say they have" - but that's not what I observed in this case! –  Robin Green Jul 5 '11 at 7:24
    
I tried what you describe with a plain C program that does a chdir(2) and a pause(3). You can still do things like rmdir the working directory. So merely having a working directory doesn't prevent name changes or even deletion of the working directory. I do a lot of "cd $PWD" commands to reconcile what zsh thinks vs where it is because of that. –  Bruce Ediger Jul 5 '11 at 13:01
add comment

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.