162

With OS X Yosemite, using the following commands, I get the following:

$ touch .a
$ touch b
$ /bin/ls
b
$ /bin/ls -A
.a  b
$ sudo /bin/ls
.a  b

It shows hidden files (that have names starting with a dot) when invoked by root and doesn’t show them (as expected) when running as a normal user. This differs from what ls on Linux (the one coming from coreutils) does.

Why does ls behave this way?

  • 141
    I misread those tags as "OSX is bad" and got really confused. – Raystafarian Jun 24 '15 at 9:41
  • 5
    It would be less confusing if tags are allowed in uppercase, BSD and OSX are more appropriate here. – ryenus Jun 25 '15 at 1:26
  • @Raystafarian quite funny, because normally is the other way around, people tries to write sentences with tags. – Braiam Jun 26 '15 at 2:26
405

It turns out this feature is not Apple-specific. This is a feature of BSD systems in general.

/* Root is -A automatically. */
if (!getuid())
    f_listdot = 1;

Initially, I was able to trace it back to the sources of 4.4BSD-Lite. It was already present in this FreeBSD commit from 1994 which is importing those sources.

The feature is also present in OpenBSD and can be found in this commit from 1995 that claims to be importing code from NetBSD, so this was already present in NetBSD.

Then one discovers the commit of NetBSD from 1993 that claims to be importing code from 386BSD, and the feature is already there. Furthermore, this commit shows that it was there during the development of 386BSD version 0.0 in 1991 which forked from BSD around 4.3, as far as I can tell.

The comment appeared for the first time during the development of 4.3BSD-Reno in this commit (27 Jun 1989) entitled “first working version of new ls”. The original comment said:

/* root sees all files automatically */

which was changed later that day (I’m not sure the timestamps are entirely correct in this repository, though) to:

/* root is -A automatically */

And only in 1992 the capital letter and the period were added turning the comment into what we have now:

/* Root is -A automatically. */

But the behaviour was present in 2BSD as of 9 May 1979 as seen in this snapshot:

Aflg = getuid() == 0;

I can’t find any actual history from those times, but there is also this snapshot of 1BSD from 1977 without those lines. And without the -A flag actually.

So it seems that the feature was introduced somewhere between November of 1977 (1BSD being developed at that moment) and the release of 2BSD in May 1979.


What I also found during this investigation, is the -I flag that was added to FreeBSD in 2005 to override this behaviour and was reworked a little bit later.

  • 52
    Also, it might be worth noting that the "feature" of hiding files by starting them with . was a simple bug - ls was only supposed to hide the . directory, not everything starting with .. Fast forward a few decades, and it's commonly used to hide dangerous files etc., while also being used to hide system configuration etc. - so it makes sense to let admins see those files (for maintaining the configuration or finding hidden malware etc.). – Luaan Jun 24 '15 at 9:08
  • 23
    Reference for Luaan's comment: plus.google.com/+RobPikeTheHuman/posts/R58WgWwN9jp (in which Rob Pike explains that hiding "dot files" started as a bug). – nibot Jun 25 '15 at 0:24
  • 2
    From the POSIX Rationale, "Some historical implementations of the ls utility show all entries in a directory except dot and dot-dot when a superuser invokes ls without specifying the -a option. When "normal" users invoke ls without specifying -a, they should not see information about any files with names beginning with a <period> unless they were named as file operands." pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html – R.. Jun 26 '15 at 3:12
  • It's far far older. I think it predates the SysV-BSD split as last time I had access to SysV systems the exact same behavior was present. – Joshua Jun 28 '15 at 3:47
  • 3
    epic answer. history learned! – Corey Goldberg Jun 29 '15 at 1:24
15

Here's a link to the source code. Note /* Root is -A automatically. */. This is a feature in Apple's version of BSD ls.

  • Interesting find. Is there also a way to suppress hidden files when doing an ls? – Mr Lister Jun 23 '15 at 17:01
  • 5
    Hm, looks like this is not an Apple-specific feature, but it comes from the BSD world? – kirelagin Jun 23 '15 at 17:30
  • 2
    Right, it is not Apple-specific. Thanks for your answer, it put me on the right track. I used the Root is -A automatically string to search for clues. – kirelagin Jun 23 '15 at 17:53
  • Mr Lister: you can suppress the display of the dot files as root with -I (capital i) on many operating systems (FreeBSD, so probably OS X as well) – Allan Jude Jun 25 '15 at 14:23
1

IIRC, there was a thread about this back in the early days of Usenet (early 80's). The feature was added as a security precaution so that malicious users couldn't easily hide files/directories/executables from the sysadmin/root. The theory was basically "root has access to everything so it should be able to see everything".

  • Sounds reasonable (even though turning a file into dot-file is a questionable way of “hiding” it). Would be great to find those archives. – kirelagin Jun 26 '15 at 11:11

protected by Community Jun 25 '15 at 21:38

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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