3

This question already has an answer here:

Hello there!

Currently, I am studying shell programming and there i just learned symbolic link , hard link, files , directories- related topics. I am trying to understand-

  1. why a directory has two links and when a directory is created - why there are . and .. files in the directory? and how they work?
  2. why . file in a directory is necessary?

Good explanations will be helpful for me.

Thanks in advance.

Best regards-
Nazmul

marked as duplicate by Ipor Sircer, G-Man, Archemar, Vlastimil, Shadur Nov 11 '17 at 19:03

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • . is useful because it provides a guaranteed name for the current directory; for example, when you type a command, the shell normally looks it up in the directories listed in $PATH, but if you say ./command then the name clearly refers to a file in the current working directory. .. is not only useful, its essential, because it provides a name for parent directory. They work as you expect -- they behave as if they were hard links to the respective directories; whether they actually exist on disk depends on the specific filesystem. – AlexP Nov 11 '17 at 14:49
6

The . and .. entries always exist in directories.

They are not specific to Linux; all Unixes have them, and POSIX is nearly requiring them. GNU Hurd and VSTa have them too. Perhaps Multics invented them. MS-DOS 3 copied them from Unix, so Windows has them also. IIRC VMS had something similar.

As soon as some program (your shell, the /bin/ls program, your or some other program using nftw(3), etc, etc....) uses opendir(3), then some readdir(3) will give . and (another call to readdir will return) .. (actually it is the underlying getdents(2)).

I don't know if they -the . and .. entries- are provided in every file system or by some common VFS layer in the kernel (and we should not care). Consider that a successful mkdir(2) creates both . and .. entries (it is at least the illusion provided by the Linux kernel).

The kernel path resolution layer handles . and .. (and /) appropriately. Read path_resolution(7). The file path is used to reference a file (which actually is some inode), and the same file can have several paths (and sometimes none).

Any system call (listed in syscalls(2)) dealing with file paths (such as open(2), unlink(2), stat(2) and many others...) goes thru that path resolution layer in the kernel.

why . file in a directory is necessary?

It is very useful in some cases. For example you could (by some program or some weird command) create a file named -r (this is very bad taste). You would use rm ./-r to remove it (because rm -r has some very different meaning). And your shell uses the $PATH variable to find executables. If you have some ls executable in the current directory (this is also very bad taste) you need to type ./ls to get it running (otherwise /bin/ls is likely to be found in your $PATH by execvp(3) or equivalent).

You could even -in principle- have a directory entry for a file named with a single return or tab character, but that is disgusting. How to remove it is left as an exercise to the reader (but it is possible with rm).

Some functions (such as dlopen(3)) are working differently with a file path containing or not a /. See this.

And .. is useful in relative file paths. See also realpath(3).

A related question is why do processes have a working directory (and each process has its own one, that is why cd needs to be a shell builtin). This is at least for convenience (and historical reasons, e.g. legacy), and also for efficiency. On some systems (think of supercomputers with petabytes of disk) a complete file path could be very long (e.g. have several hundreds of characters) and you don't want to type long file paths, or have all programs dealing with them. See also chdir(2), credentials(7), chroot(2).

On other OSes - notably MS-DOS -, working directories are -slightly- different.

BTW, files are not a must (and they are conventions and abstractions provided by the operating system kernel). Some experimental academic operating systems don't have files because they are implementing some other persistence layer. In the 1960s operating systems provided very different files (than what POSIX is requiring today).

(when you think about them, files are not necessarily the best way to organize information on current computers. Think how difficult it is for you to find a photo amongst many thousands of them, or a letter you wrote many years ago, on your laptop. Let's hope that future OSes will have something better)

Read Operating Systems: Three Easy Pieces (freely downloadable). Implement -as an exercise- your own unix shell (or study the source code of existing ones, since they are free software). See also this.

  • Actually, working directories are the same in Win32. – JdeBP Nov 11 '17 at 16:20
  • Not only do you not want to type a long argument (file path or other), but arguments take up space in the shared buffer for arguments-plus-environment. Better to save a long path once in the environment and refer to it with a short alias than to waste buffer space in every command. – chepner Nov 11 '17 at 16:20
  • 1
    @JdeBP: Are you sure that working directories are the same on Windows? On MSDOS each drive A:, B: had its own wd (but I used it only in the 1980s and I am becoming old, so perhaps I am wrong) – Basile Starynkevitch Nov 11 '17 at 16:20
  • @chepner: you are right, but today with 16Gbyte RAM in every laptop we don't care. – Basile Starynkevitch Nov 11 '17 at 16:30
  • 1
    Yes, quite sure. Win32 is not MS-DOS and its working directory semantics are exactly as described here: one working directory per process. This is famously one of the API differences. Also note that POSIX.1 does not require the existence of .. in all directories. – JdeBP Nov 11 '17 at 16:30

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