Subject: Re: bug#14189: ls -d bug ??

From: Bob Proulx <[email-masked]>
Date: Thu, 11 Apr 2013 15:13:19 -0600

tags 14189 + notabug
close 14189
thanks

http://www.gnu.org/software/coreutils/faq/#ls-_002dd-does-not-list-directories_0021

[email-masked] wrote:
> Once in a blue moon, a person would like to view the subdirectories of the
> directory you are in, without seeing all the various files.

Thank you for your report.  However what you are reporting is due to a
misunderstanding of the usage of the command.

> Since you can use the ls command to view the files and directories that are
> contained in your pwd, one would THINK the intuitive method would be to type ls
> -d.

But that is not correct.  And it isn't as documented.

> Interestingly, the MAN page seems to indicate that this is the way to go,

You have fallen into a trap.  The computer is executing a program and
does *exactly* what it was programmed to do.  The documentation is
written to say exactly what the program does.  But you are thinking
like a human and making an interpretation and an extrapolation based
upon what you *want* it to do.  Those are different things.

The GNU ls documentation says this:

  `-d'
  `--directory'
     List just the names of directories, as with other types of files,
     rather than listing their contents.  Do not follow symbolic links
     listed on the command line unless the `--dereference-command-line'
     (`-H'), `--dereference' (`-L'), or
     `--dereference-command-line-symlink-to-dir' options are specified.

The GNU ls man page says:

   -d, --directory
     list directory entries instead of contents, and do not
     dereference symbolic links

The online standards documents say:

  http://pubs.opengroup.org/onlinepubs/009695399/utilities/ls.html
  -d
    Do not follow symbolic links named as operands unless the -H or -L
    options are specified.  Do not treat directories differently than
    other types of files.  The use of -d with -R produces unspecified
    results.

Each and every one of those applies the -d option to the arguments of
the ls command.  But what are the arguments to ls?  If you type in ls
with an argument then there is no doubt.

  $ mkdir foodir
  $ touch foodir/foofile1
  $ ls foodir
  foofile1

At that point there is no doubt.  You are asking it to list foodir.
Let's apply the -d option.

  $ ls -d foodir
  foodir

The -d option clearly applies to foodir.  Therefore it prevents it
from listing the contents.  It lists only the name of the directory.
This is as documented for -d that it lists only names and using -d
prevents it from listing the directory argument contents.

But what happens if you don't give ls an option?  What is the default
argument to ls?  The GNU ls documentation says:

  10.1 `ls': List directory contents
  ==================================

  The `ls' program lists information about files (of any type, including
  directories).  Options and file arguments can be intermixed
  arbitrarily, as usual.

     For non-option command-line arguments that are directories, by
  default `ls' lists the contents of directories, not recursively, and
  omitting files with names beginning with `.'.  For other non-option
  arguments, by default `ls' lists just the file name.  If no non-option
  argument is specified, `ls' operates on the current directory, acting
  as if it had been invoked with a single argument of `.'.

That last line says it.  Let me repeat it for emphasis.

  If no non-option argument is specified, `ls' operates on the current
  directory, acting as if it had been invoked with a single argument
  of `.'.

If no arguments are specified then ls lists '.' as if it had been
invoked "ls .".

> however, regardless of what directory you are in, if you type
> 
> ls -d

If you run "ls -d" then we know from the documentation that it is the
same as saying "ls -d ." and that will simply list the name of it
because the -d option says only list the names of directories.
Therefore the expected behavior is that it must only list the name of
the '.' directory.

> you don't get the expected result, but rather you get:
> .

Unfortunately you had incorrect expectations! :-)

Any other result would be a bug.  I hope I have convinced you that
that ls is doing the right thing here and behaving as documented even
if it isn't doing what you want it to do.

This is a common misunderstanding and is one of the FAQ entries.
Please read the FAQ entry here:

  17 ls -d does not list directories!
  http://www.gnu.org/software/coreutils/faq/#ls-_002dd-does-not-list-directories_0021

> Wull DUH, like I couldn't figure out that I was in a directory.  If I wanted to
> get more info on that I'd type pwd !

If you didn't want it to list only the name of the directory and not
the contents then why did you use the -d option?  Since -d
specifically prevents it from listing the contents.

> ls -d, I would think, would tell you the same data that ls would tell you, minus
> the individual files.
> (In  other words - show all the data with a "d" in the permissions, but not show
> the ones that don't have a "d" in the permissions).

Perhaps you want this?

  $ ls -log | grep ^d
  $ ls -log | grep -v ^d

Or one of these:

  $ find . -maxdepth 1 -type d -ls
  $ find . -maxdepth 1 -type d -exec ls -logd {} +

I definitely recommend reading about "find".  It is an extremely
useful command.  Knowledge of it will apply to all of the utilities
uniformly.

I have gone ahead and closed this since it isn't a bug.  But please
feel free to continue the discussion.  It will all go into the bug log
and perhaps help the next person who searches for the information.

Bob