14

If I run ls -a

user@users-MacBook-Pro:~$ ls -a
.           ..

I get . and .. (current directory and parent directory?)

Is there a reason why they show up after ls -a, do they do anything interesting?

  • 23
    it is unclear what you are asking, since you already know what they represent – jsotola Feb 19 at 0:54
  • 4
    Maybe I mean to ask why they show up when you ls -a. Like is there a point to them showing up there? They don't seem to be adding anything useful. – Margo Oka Feb 19 at 1:01
  • 5
    Could you edit your question and clarify what you're asking? As jsotola said you already know what these are, and the -a option is clearly documented in man ls as "do not ignore entries starting with .", so what is the question? They appear because you are using an option specifically designed to make them appear. – terdon Feb 20 at 14:15
  • 5
    You are aware that they actually exist on disk in the folder and therefore should show up? – Thorbjørn Ravn Andersen Feb 20 at 23:57
  • Try it on the root directory / – jsejcksn Feb 21 at 12:53
67

Because -a means show all files. It is useful when combined with -l. As to why show those useless files when not using -l, because of consistency, and because Unix does not try to double guess what is good for you.

There is an option -A (for at least GNU ls) that excludes these two (.., and .).

Interestingly the idea of hidden files in Unix came about by a bug in ls where it was trying to hide these two files. To make the code simple the original implementation only checked the first character. People used this to hide files, it then became a feature, and the -a option was added to show the hidden files. Later someone was wondering, the same as you, why . and .. are shown, we know they are there. The -A option was born.

Note: Unix has a much looser meaning of file than you may have.
FILE ⊇ {normal-file, directory, named-pipe, unix-socket, symbolic-link, devices}.

| improve this answer | |
  • 2
    The OP is on a Mac. Does it have the -A option? – roaima Feb 19 at 8:05
  • 14
    -A is a POSIX option for ls. pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html It makes ls show hidden names but excludes . and .. "(if they exist)". – Kusalananda Feb 19 at 14:50
  • 6
    /bin/ls on macOS Mojave (10.14) supports the -A flag. (macOS is POSIX certified, although offhand I’m not sure which OS versions are certified as complying with which POSIX versions.) – bdesham Feb 19 at 19:21
  • 3
    char and block device files are another 2 types of file, if you were trying to write an exhaustive list. – Peter Cordes Feb 19 at 20:01
  • 3
    @JoelFan: On what system do you see that? It's definitely there on MacOS, and arguably needs to be there on any POSIX-compliant system, although POSIX.1-2017 chapter 4.13 does permit some flexibility in where it links to. (The usual choice, apart from some old and obscure systems, is that /.. and /. both link to the root directory itself.) – Ilmari Karonen Feb 21 at 3:16
43

Like is there a point to them showing up there?

They show the ownership and permissions. That is often the most important thing to check when you have two users and one is saying they cannot see the other person's file that they were expecting to.

| improve this answer | |
  • 1
    You can check the properties of a directory by just writing the name out on the command line (ls -ld /some/dir, or even ls -ld . if you need to point at the current directory without using its name). There's really no need for -a to list them out just for that. – ilkkachu Feb 19 at 15:12
  • 2
    @ilkkachu: sure, but if you don't want to see . and .., use ls -A (--almost-all) which is otherwise the same as ls -a. (Other comments say that option's documented by POSIX.) – Peter Cordes Feb 19 at 19:58
  • Also to add you can use this to see the date/time modified of current and parent directory – QuickishFM Feb 20 at 9:33
  • 1
    But in the original ls -a they give zero information! With -l option, yes. But then, with perms, owners, time on two lines: why not give also the names: people (not me;) have $PWD in the prompt, because ls -dl . only shows a dot, and you don't want to bother with pwd just for that. – user373503 Feb 20 at 16:19
  • @PeterCordes, err, yeah, sure, we can use that now. But I understand it didn't exist originally, and I don't really see any reason why ls -a couldn't have hidden . and .. from the start. Being able to see their permissions on each and every ls -a doesn't sound that useful to me, since we know they're there, and can check the permissions with ls -d .. directly if required. They're not an interesting answer to "what files have we here", which is what plain ls or ls -a (without a file argument) is mostly for. – ilkkachu Feb 21 at 8:54
8

As shown in https://ss64.com/bash/ls.html when you add the -a parameter to ls
you get all entries, even those which begin with .; they are considered to be hidden entries, and not shown with a simple ls.

| improve this answer | |
  • 13
    @MargoOka They are files. – Kamil Maciorowski Feb 19 at 1:09
  • 1
    . and .. are directories right? are directories equivalent to files? edit: just clicked the link haha interesting! – Margo Oka Feb 19 at 1:12
  • 5
    @MargoOka "Directory" is a type of file (a "filetype"), just like "regular file", "named pipe", "socket" and others. – Kusalananda Feb 19 at 14:52
  • 3
    @Margo Oka: In *nix, just about everything is a file. For instance, look at /proc, /sys, and /dev. – jamesqf Feb 19 at 18:15
  • 1
    "they're not files though " - Your question did not ask about files. – K7AAY Feb 19 at 18:17
6

Is there a reason why they show up after ls -a?

I'd wager a guess it's just a historical accident, like so many things are.


According to a story by Rob Pike, "hidden" files (dotfiles) were created by something of an accident:

Long ago, as the design of the Unix file system was being worked out, the entries . and .. appeared, to make navigation easier. I'm not sure but I believe .. went in during the Version 2 rewrite, when the file system became hierarchical (it had a very different structure early on). When one typed ls, however, these files appeared, so either Ken or Dennis added a simple test to the program. It was in assembler then, but the code in question was equivalent to something like this:

if (name[0] == '.') continue;

This statement was a little shorter than what it should have been, which is

if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;

but hey, it was easy.

Two things resulted.

[...] Second, and much worse, the idea of a “hidden” or “dot” file was created. As a consequence, more lazy programmers started dropping files into everyone's home directory.

Based on that, it doesn't seem far fetched to guess that ls -a was added then to show the dotfiles created by those lazy programmers. And the simple implementation for that would be just disable the above test in turn, resulting in . and .. showing, again.

Regardless of the history, showing them is the behaviour specified in the standard now:

-a
Write out all directory entries, including those whose names begin with a <period> ( '.' ).

But there's also ls -A to do the slightly saner thing. I don't know how much newer that one is:

-A
Write out all directory entries, including those whose names begin with a <period> ( '.' ) but excluding the entries dot and dot-dot (if they exist).


Do they do anything interesting?

Listing them with plain ls isn't very interesting.

But looking for e.g. . in /path/subdir gives the same inode as looking for subdir in /path. The ownership and permissions of the directory control who can access files there, so that information might be nice to have available through ., too. However, one can always do ls -ld . or ls -ld /path/subdir if they need the properties of the directory itself.

| improve this answer | |
  • That story sounds very much like a fable / moral story, where the facts take a backseat to the overall "message". You will already find ls -a (with the same meaning as today) in the unix manual from from 11/3/1971 (page 67) – Uncle Billy Feb 20 at 0:54
  • "Version 2 rewrite" is not 2nd Edition, probably. Pike can't be hallucinating about a non-hierarchical epoch. 1st Ed. has mkdir, and it directly mentiones the "standard entries": DESCRIPTION mkdir creates directory dirname. The standard entries "."and ".." are made automatically. But there was a time before . and .. --- when the fs was very diefferent, and not hierarchical. – user373503 Feb 20 at 12:59
  • @UncleBilly, I never claimed to know if the story is true -- I couldn't, since I wasn't there. (Also, that was originally posted on Google+, which doesn't work any more, so I couldn't link to the original either.) But true or fable, it doesn't seem implausible that an original implementation was excessively simple, and then things just got stuck at that. In other words, I suppose it comes down to "because it always worked like that" or equivalent. – ilkkachu Feb 20 at 14:05
  • Nope, the file system had directories (it was "hierarchical") from the very beginning, according to 1 of the 2 people who, unlike Rob Pike, were there at the time (but who unfortunately is no longer here with us). According to the same, it didn't have paths tho -- to access a file in another directory you had to create a hard link in the current directory. – Uncle Billy Feb 21 at 6:54
  • And that, combined with the fact that a dir listing was printed on paper, gives the astute reader enough hints both for why . and .. exists in the 1st place and for why people had to use "hidden" files instead of stashing them in a separate directory. No need for ridiculous mystical-romantic stories about historical accidents. – Uncle Billy Feb 21 at 6:56
5

This ls option requires to show all files with ls -a...

But the physical existence of . and .. in most filesystems is an artefact from the 1970s, when computers have been very tiny and people tried to find implementations that need only a small code size. This resulted in making hard links to the current directory and to the parent directory.

Since more than 30 years this is seen as a mistake.

In fact, UNOS (the first UNIX clone from 1980) did not have . and .., my WOFS (the first copy on write filesystem) and ZFS do not have them as well.

What is required by POSIX is just to handle dir/. and dir/.. the expected way, when passed to syscalls that handle filenames.

Unfortunately, most software today is still written badly and gets into problems when these entries are missing, this is why ZFS emulates the existence....

As a result, it is unspecified whether ls -a prints lines for . and ... This depends on the filesystem. If you are on a filesystem that does not include physical entries for . and .. and that does not pretend to have them (like ZFS), you need to call: ls -ld . ..

BTW: POSIX decided recently that echo .* is no longer required to include . and .., even when they physically exist. Once all shells behave this way, this will be a big win.

| improve this answer | |
  • 2
    While this is interesting background, it seems to imply that if they weren't physical entries in the file system, you'd never want ls to show them. But as another answer points out, the combination ls -al is useful for showing the permissions of the current and parent directories, which would otherwise require running something like ls -l ..; ls -l ../.. and looking for the relevant names. – IMSoP Feb 19 at 14:36
  • Correct, I updated the answer. ls -a does not grant output for . or ... – schily Feb 19 at 14:47
  • 1
    “Not required” and “forbidden” are two different things. The former implies that it is allowed, which implies no motivation to change the behavior everyone is accustomed to. – WGroleau Feb 20 at 16:38
  • This is not how POSIX works.We first permit it in the next version of the standard. Then we may require it in the version after the next. This will be in 10 years. – schily Feb 20 at 20:48
4

In Unix (folklore has it that by mistake) file/directory names starting with . weren't shown by ls (because names . and .. had been reserved for "this directory" and "parent of this directory", and showing them was considered useless clutter). So using that quirk people started using names like .profile or .something-or-other-rc (the RC is from Run Command, startup file name for yet another long defunct system) for files (and directories) that were "uninteresting". Thus ls -a(show all), and of course it'll show . and ..

| improve this answer | |
  • +1 for mentioning what the files actually do. I was looking to see if someone had mentioned that, and was going to post the answer if it hadn't already been done. – Charlie Feb 22 at 1:10
1

as the design of the Unix file system was being worked out, the entries . and .. appeared, to make navigation easier

No answer seems to see any use in these entries in the first place. They somehow stem from the hierarchical linked list. "Easy navigation": not with ls, but with a C program using readdir(3) or so.

I believe .. went in during the Version 2 rewrite, when the file system became hierarchical


Is there a reason why they show up after ls -a, Do they do anything interesting?

A) Yes (historical/technical reasons) B) Yes, unless you find cd .. uninteresting. (Or clicking on (pseudo)file .. in a graphical file browser)

(OK, they don't have to show up to be used...that's why it's an option and there is also -A)


Even find does it in an empty dir:

]# find
.

Like that I know: find did find something: nothing.


]# stat  . .. |grep Device
Device: 36h/54d         Inode: 154051      Links: 6
Device: 803h/2051d      Inode: 393219      Links: 26
]# cd /
]# stat  . .. |grep Device
Device: 803h/2051d      Inode: 2           Links: 18
Device: 803h/2051d      Inode: 2           Links: 18

This defines the top of the hierachy. The direntries of . and .. are identical in the top dir /. And if you don't realize it, a cd .. is just like cd .. I don't get a message, it just works/fails silently.


Only the fields d_name and (as an XSI extension) d_ino are specified in POSIX.1. Other than Linux, the d_type field is available mainly only on BSD systems.

struct dirent {
           ino_t          d_ino;       /* Inode number */
           off_t          d_off;       /* Not an offset; see below */
           unsigned short d_reclen;    /* Length of this record */
           unsigned char  d_type;      /* Type of file; not supported
                                          by all filesystem types */
           char           d_name[256]; /* Null-terminated filename */
       };

The readdir() function returns [a pointer to] a dirent structure representing the next directory entry in the directory stream pointed to by dirp.

Without a type field, you (ls) would have to look at the inode's content before it can tell file or dir or pipe. And without the . and .., you would have to store these inodes in a variable.


This is how these entries can simplify navigation, for the script and the user. Choice "1" does it with the current directory, pretending . is contained in it, as a dir.

]# select ans in $(ls -af); do ls -l $ans; done
1) .
2) ..
3) child3
4) child2
5) child1
#? 1
total 0
drwxr-xr-x 2 root root 40 Feb 21 07:36 child1
drwxr-xr-x 2 root root 60 Feb 21 07:40 child2
drwxr-xr-x 2 root root 60 Feb 21 07:40 child3
#? 2   
total 0
drwxr-xr-x 5 root root 100 Feb 21 07:36 myself
drwxr-xr-x 2 root root  40 Feb 21 07:37 sibling1
drwxr-xr-x 2 root root  40 Feb 21 07:37 sibling2
#? 3
total 0
-rw-r--r-- 1 root root 0 Feb 21 07:40 f.b
#? 4
total 0
-rw-r--r-- 1 root root 0 Feb 21 07:40 f.a
#? 5
total 0

(It would be more interesting if it cds and then lists the new dir as a select again, and so on...)

| improve this answer | |
0

Is there a reason why they show up after ls -a, do they do anything interesting?

Well, they show up after ls -a because that is the function of the -a switch to ls. You asked ls to show you files beginning with a dot, and so it did. I'm afraid there isn't a better answer; that's what -a is for.

The interesting thing they do is allow relative path specification. You can specify a file location relative to the current default, rather than as an absolute path from root. This is very useful as well as being interesting.

| improve this answer | |
0

No one seems to have explicitly mentioned the basic premise of Unix-like systems1:

Everything is a file.

This includes directories.

Since ls -a lists all files and directories are files, it stands that . and .. would be included.

"Do they do anything interesting?"

Yes, they do. They give you handy references; . represents the current directory and .. represents the parent directory. This allows you to do stuff like mv /file/elsewhere . and cd ... Of course, this is pedantry and you probably already knew this. :)


1 Although @ctrl-alt-delor's answer does imply it.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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