-3

A historical question. I tried searching for the answer to this, but no luck.

Every directory contains a "." and "..", even ROOT (/) contains "..", but why? Neither seem necessary from my admittedly limited perspective.

  1. To run a script in the current directory ./script.sh. But if "." didn't exist, then we could just use bash script.sh.

  2. To change to the parent directory cd ... But if ".." didn't exist, then I imagine a command could exist like cd --parent 1 (go up one parent directory)

So rather than mandatory, the dot and dotdot seem to be more of a shorthand.

As downsides, they prevent the creation of any file named "." or "..". Also, they can make listing/manipulating files that start with a dot more difficult/error prone.

rm -r .* # delete current and parent directory?

To be clear, I'm not asking for a change. I'm just curious how we ended up here? Why that choice was made instead of any other way of referring to these two directories?

Edit: Some people are voting down my question, but not giving any feedback on how to improve it.

Rucent88
  • 1,880
  • 4
  • 24
  • 37

2 Answers2

3

The . and .. directories are part of the POSIX unix specification.

Your suggestions to change commands to work without them would make things more complex, not less complex. And historical reasons.

If we did not have . to refer to the current directory, how would you do it? Maybe with an empty string? Using .. for parent directory does seem like a shortcut, but adding options to every command in the system to avoid using it is not a good solution either. Some (historical) systems also had ... to refer to two parent directories up, but this was likely only a shell shortcut.

The .. directory is useful in relative pathnames, which is a good way to make things portable, frequently better than hardcoding full pathnames.

Traditionally, the . directory was included in $PATH. Later it was realized that including the current directory in the path was a security risk -- what if you cded to a directory that contained malicious executables that used the same name as system commands? So it was removed from the default path, and now to run things in the current directory, you need to do so explicitly by saying ./command; Using bash command instead starts two processes instead of one.

user10489
  • 6,740
  • "Some (historical) systems also had ... to refer to two parent directories up, but this was likely only a shell shortcut." what were those systems? –  Aug 15 '21 at 17:53
  • I remember seeing and using that, but don't remember where. Sorry, lost to the sands of time. – user10489 Aug 15 '21 at 18:01
  • 2
    I think the 4DOS shell for DOS supported cd ..., there's a supporting mention of that here: https://news.ycombinator.com/item?id=23113308 – ilkkachu Aug 15 '21 at 19:55
  • 1
    @ilkkachu yes, it did (and still does), as does its descendant, TCC. It supports any number of dots, each additional dot goes up one more level (until one runs out of levels). – Stephen Kitt Aug 16 '21 at 07:35
2

To run a script in the current directory ./script.sh. But if "." didn't exist, then we could just use bash script.sh.

Yes, but that requires knowing what the right interpreter is. Perhaps someone rewrote it it Perl but kept the name for compatibility, or perhaps the name was actually just othertool, without an extension. Running it as ./othertool lets the system take care of that, via the hashbang line (#!). Or other magic numbers, since the program could be a binary file too. Of course you could just add . to PATH, too.

That's a post-facto rationalization though, since I'm pretty sure hashbang lines didn't exist from the start (they're not POSIX even now).

To change to the parent directory cd ... But if ".." didn't exist, then I imagine a command could exist like cd --parent 1 (go up one parent directory)

Yes, it probably could exist. But that would mean every time you wanted to use relative paths, it'd be harder. You couldn't do something like mv ../foobar/blah . Perhaps some programs would include some way to do that, either via a command line option, like your --parent, or via some string prefixed to the path, e.g. %up/foobar/blah, or such.

Similarly you couldn't make relative symlinks point at higher levels of the tree. A symlink in /foo/bar/link pointing to /foo/other/file would need to spell the name out, instead of just containing the relative reference ../other/file. The link would break when foo was renamed, or there would have to be a mechanism for rewriting any such symlinks on any renames...

Even if it's not too commonly needed, having a standard way to move up in the filesystem tree makes stuff like that more general, and general is better in cases where it is needed.

Also, the filesystem needs some way of finding the parent of a given directory for even cd --parent to work, and the straightforward and obvious implementation is to store it exactly like every other directory related to that directory, with a special name.

. is similarly useful so that you can do cp /some/where/file.txt . without a special way of referring to "here". Though as I recall, e.g. the COPY command on DOS/Windows defaults to the current directory as destination, and e.g. GNU find and GNU grep with -r start from the current directory by default. But that also means every program must have a special case for the current directory.


Of course, the names could be something completely different, and it might not have been a bad idea to e.g. forbid creating other files with names starting with dots. Or to reserve some particular character for those special names, and forbid using that character at all in other filenames.

ilkkachu
  • 138,973
  • A line beginning with #! is more commonly called a shebang-line - In fact on wikipedia "hashbang" redirects to "shebang". But apart from that I like this answer for pointing out that . and .. can be used in many more ways than the OP had addressed in the question. – Henrik supports the community Aug 15 '21 at 21:54
  • @Henriksupportsthecommunity, it also says of the # sign that it's called the "number sign" or "hash" or "pound sign". Also, "bang" is a (slang?) name for the exclamation mark, so #! is a hash and a bang, so a hashbang. A dear child has many names. – ilkkachu Aug 16 '21 at 07:32