161

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?

3
  • 142
    I misread those tags as "OSX is bad" and got really confused. Jun 24, 2015 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, 2015 at 1:26
  • @Raystafarian quite funny, because normally is the other way around, people tries to write sentences with tags.
    – Braiam
    Jun 26, 2015 at 2:26

3 Answers 3

404

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.

7
  • 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, 2015 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, 2015 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 Jun 26, 2015 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, 2015 at 3:47
  • 3
    epic answer. history learned! Jun 29, 2015 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.

4
  • Interesting find. Is there also a way to suppress hidden files when doing an ls?
    – Mr Lister
    Jun 23, 2015 at 17:01
  • 5
    Hm, looks like this is not an Apple-specific feature, but it comes from the BSD world?
    – kirelagin
    Jun 23, 2015 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, 2015 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, 2015 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".

1
  • 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, 2015 at 11:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .