A directory is (conceptually) a special "file" which contains a list of names, and the inode numbers those names point to. Some of names can be subdirectories. There is a special entry ..
which points to the parent directory.
So, its clear, changing the name of a file is easy: you just change the name in the directory entry, nothing else. This holds whether the file is actually a file, or is a "file" used to store another directory's contents. Indeed, the same rename
syscall does both.
Copying, however, is a much less trivial operation. You could just copy the directory "file", but then you'd have two directories where are the files are the same (they'd be hardlinks). If you had a system that allows hardlinks to directories, those would be to, but since no modern system allows that, at least to non-root, you have to do that copy for each subdirectory. You can actually ask cp
for this behavior with cp -lR
: -l
for hard link, -R
for that recursion.
But leaving everything linked is likely not what you want. Instead, you want cp
to copy each file. That's a fairly expensive operation: each file must be read into memory, and written back out to disk in a second location. It actually takes several syscalls, to open, read, write, and close the files, and that has to be repeated for each file.
Traditional filesystems work this way on disk, too. There isn't any way to copy a bunch of files, other than to go through each one individually and copy it, and those are the types of filesystems that were in use when the basic command line utilities were designed.