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?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityBecause -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}.
-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)".
/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.)
/..
and /.
both link to the root directory itself.)
Feb 21, 2020 at 3:16
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.
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.
.
and ..
, use ls -A
(--almost-all
) which is otherwise the same as ls -a
. (Other comments say that option's documented by POSIX.)
Feb 19, 2020 at 19:58
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.
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.
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
.
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 typedls
, 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.
ls -a
(with the same meaning as today) in the unix manual from from 11/3/1971 (page 67)
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.
.
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.
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.
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.
ls -a
does not grant output for .
or ..
.
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 ..
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 cd
s and then lists the new dir as a select again, and so on...)
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.
No one seems to have explicitly mentioned the basic premise of Unix-like systems1:
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.
-a
option is clearly documented inman 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./