That is, do they take up storage space? Is dot a copy of the current directory? Could I say that dot and double dot are subdirectories of the current directory?
A directory is logically a table used to map names to filesystem objects such as files or directories. Files can have multiple names and can be in multiple directories. The extra directory entries are links to the same file; the file itself is not duplicated. The same is true for directories. The '.' entry is a name which always maps to the directory that it is in. '..' maps to the parent, but in the case of the root directory it maps to itself.
Related
I was wondering why every file has 1 link to itself.
I'll try to be more clear.
By inserting from bash the command " ls -l " you'll end up with a list of files each preceded by different data divided in columns. The number of links to a file is in the third column. Can someone explain me why a file has that information setted to 1 instead of 0?
I get why the directories have two, if you explore one you'll find the " . " and the " . . " subdirectories, the former points at the directory itself, while the latter to the previous directory, but the file can't contain the " . " subdirectory since it's a file, so shouldn't it be 0?
Because there is nothing special about the first hard link (soft links are different, they're really just special files containing the textual target) to a file, it's just a directory entry that refers to the inode behind it.
This is a consequence of the decision to separate data (inode) from references to the data (directory entry).
So don't think of the file being one directory entry, with other files linked to it. Think instead of the data in the file being the thing, with as many directory entries as you need referring to it. When you hard-link directory entry a to an existing b, you're really linking it to the inode behind b, and they are equals in every sense of the word. The data is only ever destroyed when the final hard link to it is disconnected.
The filename you see is a hard link to the underlying object that represents the file, and ones with 0 links get automatically removed by the filesystem.
You have misinterpreted the number of links pointing to the file's inode, with the fact of having a link pointint to itself (see below).
Just consider the possibility of having a link... a link is an entry in a directory, that associates a name with an inode. The inode represents all the administrative data that is stored in a file (or a directory) and stores things like the permission bits, the dates of last read, last write or last inode change, pointers to the file's data blocks, etc.
There's one integer field in each inode that reflects the number of links that point to it (and this is what ls shows). This is needed for efficiency reasons, as it is redundant information. Just navigating the whole filesystem we can determine the number of directory entries that point to the same inode... but that is impractical to do, so the link count is maintained each time a node is linked or unlinked. So the next question is: Why is the number of directory entries pointing to the file's inode necessary? There's a bookkeeping reason. In order to detect when it reaches zero, as because of that, the kernel keeps the number of links pointing to an inode so it can free all the blocks belonging to the inode and the inode itself in order to recover the data after a file is removed (unlinked) the last time (when the counter gets down to zero)
Normally, a file has at least one such link, but it can have more. If you execute a command like:
ln foo bar
you are creating an alias for file foo, that now is called also bar. If you make your directory listing now, you'll see both file entries having 2 in the number of links field. More on, if you execute
ls -li foo bar
you'll see a first column, showing the inode number (this is a unique id for a file in a filesystem) of both files as the same inode... If you change the permissions to one of the links, you'll see the other file name his permissions changed also... this is because both filenames are aliases for the same file.
With respect with my first paragraph, a number of links is not the same thing as pointing to itself. Every directory has an entry that points to the directory's inode of the directory itself. This is the entry . that every directory has (this entry allows you to execute the ls command without parameters, for example, as when you don't specify parameters, the ls command uses . as the directory to list) and that makes that a directory has always 2 as a minimum (the 1 you observed for a file, plus the link of the . directory every directory has, for that number (check this and you'll see that this is an invariant of unix systems) Directories have 2 + number_of_subdirectories in its inode (one for the entry in the parent directory pointing to the directory itself, one for the directory entry . in the directory itself, and one for each subdirectories' entry .. parent directory, in the subdirectories of this directory) Check the numbers, it doesn't fail. And for files is the number of links (or aliases) a file can have. You cannot see files with 0 links as you are listing a directory, those files, case of existing, are being handled by the kernel, in the task of erasing them (freeing the blocks they used) Directories cannot have different aliases or names as files in order to conserve the hierarchical directory structure, only the two exceptions for . and .. are permitted and these are maintained (and enforced) by the kernel.
I have a directory with files and other directories inside. I want to normalize all file paths inside it to lower-case. By this I mean that:
Whenever there are two paths ./A/b/d and /a/b/c under the directory (that I call .). Then A and a should be merged, with the name a. This can occur at any level.
Suppose that there are no file repetitions. That is, if all paths are converted to lowercase, there will be no file conflicts (but many directories will have to be merged).
How can I do this?
In case you are wondering, I am trying to copy a directory from linux to Mac (which is case-insensitive).
Is there anything special about directories which start with a dot . in Linux (Ubuntu), such as ~/.vim?
Thanks.
Files and directories whose names begin with a dot (.) by default are not displayed in directory listings by the standard command ls. Therefore, they are traditionally used to store settings, preferences, etc.. Directory ~/.vim in particular surely contains personal preferences and settings for the text editor vim.
There are also two special directory names in this class: the directory named simply . is an alias for the same directory in which it appears (a self reference), and the directory named .. refers to the parent directory of ..
Many graphical file browsers ignore the convention of hiding file names beginning with a ., so it is not necessarily correct any longer to call these files "hidden". Nevertheless, that terminology persists.
In UNIX-like environments, a filename preceded by a dot indicates a hidden file. It's mainly a mechanism to decrease clutter in directory listings. You can get a listing of hidden files by passing the -a parameter to ls
Those are hidden. You'd need to apply extra effort to see them.
The ls -ai command shows that . and .. have their inodes the same as the current directory and parent directory, respectively.
What exactly are . and ..?
Are they real files or even hard links? But as I have known, it's not allowed to create a hard link to a directory.
. represents the directory you are in and .. represents the parent directory.
From the dot definition:
This is a short string (i.e., sequence of characters) that is added to
the end of the base name (i.e., the main part of the name) of a file
or directory in order to indicate the type of file or directory.
On Unix-like operating systems every directory contains, as a minimum,
an object represented by a single dot and another represented by two
successive dots. The former refers to the directory itself and the
latter refers to its parent directory (i.e., the directory that
contains it). These items are automatically created in every
directory, as can be seen by using the ls command with its -a option
(which instructs it to show all of its contents, including hidden
items).
They are special name-inode maps which do count as hard-links (they do increase the link-count) though they aren't really hard-links, since, as you said, directories can't have hard-links. Read more here: Hard links and Unix file system nodes (inodes)
. represents the current directory that you are using and
.. represents the parent directory.
Example:
Suppose you are in the directory /etc/mysql and you wanted to move to the parent directory, i.e. /etc/. Then use cd..:
/etc/mysql> cd ..
And if you wanted to set the path of one file in the current directory bash file, use . with file name like this: ./filename
They are not hard links. You can more think of it like a shorthand for this directory (.) and parent of this directory (..).
Try to remove or rename . or ... Then you understand why it is not a hard link.
I have two rfs dirctories I would like to compare to each other with diff. Both directories represent a rfs of some other system, and may contain links. If those links are absolute, they will point to something useless.
For example, I have one rfs with the following symlink (inside the rfs):
/usr/test -> /home/test/file1
Now I have this complete rfs inside a directory named /home/user/compare, and the absolute paths of both files mentioned above are
/home/user/compare/usr/test
/home/user/compare/home/test/file1
Clearly, the symlink /home/user/compare/usr/test does not point to the right file. And because of that a comparison with the files in /home/usr/compare with some other rfs directory will fail for those symlinks.
Is it possible to setup diff so it assumes not / as root but /home/user/compare as root (for the comparison), so that the given absolute symlink points to something valid, and diff takes it into account?
Maybe there is a similar Linux command I can use for that?