On OS X, why does `sudo ls` show hidden (dot) files?

161

29

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?

kirelagin

Posted 2015-06-23T15:36:05.113

Reputation: 2 664

141I misread those tags as "OSX is bad" and got really confused. – Raystafarian – 2015-06-24T09:41:23.703

5It would be less confusing if tags are allowed in uppercase, BSD and OSX are more appropriate here. – ryenus – 2015-06-25T01:26:40.813

@Raystafarian quite funny, because normally is the other way around, people tries to write sentences with tags. – Braiam – 2015-06-26T02:26:00.870

Answers

403

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.

kirelagin

Posted 2015-06-23T15:36:05.113

Reputation: 2 664

52Also, 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 – 2015-06-24T09:08:25.150

23

Reference for Luaan's comment: https://plus.google.com/+RobPikeTheHuman/posts/R58WgWwN9jp (in which Rob Pike explains that hiding "dot files" started as a bug).

– nibot – 2015-06-25T00:24:26.357

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." http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html

– R.. GitHub STOP HELPING ICE – 2015-06-26T03:12:22.070

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 – 2015-06-28T03:47:33.937

@Joshua: I'm confused by your comment. This answer traces the feature to 1977-1979, which is before System V existed. – ruakh – 2015-06-28T18:31:35.143

3epic answer. history learned! – Corey Goldberg – 2015-06-29T01:24:25.723

Maybe it's just convergent then. – Joshua – 2015-06-29T02:27:38.470

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.

fd0

Posted 2015-06-23T15:36:05.113

Reputation: 1 222

Interesting find. Is there also a way to suppress hidden files when doing an ls? – Mr Lister – 2015-06-23T17:01:29.193

5

Hm, looks like this is not an Apple-specific feature, but it comes from the BSD world?

– kirelagin – 2015-06-23T17:30:23.553

2Right, 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 – 2015-06-23T17:53:53.270

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 – 2015-06-25T14:23:46.147

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".

tachijuan

Posted 2015-06-23T15:36:05.113

Reputation: 21

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 – 2015-06-26T11:11:52.003