1

The command ls -d */ only lists directories as follows

Desktop/    Downloads/  Pictures/  snap/       Videos/
Documents/  Music/      Public/    Templates/

The command ll -d */ limits the results to directories as well however appends an additional forward slash.

(ll is an alias for ls -alF)

drwxr-xr-x 2 ec ec 4096 Jan 12 06:39 Desktop//
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Documents//
drwxr-xr-x 7 ec ec 4096 Jan 12 21:12 Downloads//
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Music//
drwxr-xr-x 2 ec ec 4096 Jan  5 20:47 Pictures//
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Public//
drwxr-xr-x 3 ec ec 4096 Jan  5 15:16 snap//
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Templates//
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Videos//

If the command ls -ald */ is run, it does not include an additional forward slash.

drwxr-xr-x 2 ec ec 4096 Jan 12 06:39 Desktop/
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Documents/
drwxr-xr-x 7 ec ec 4096 Jan 12 21:12 Downloads/
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Music/
drwxr-xr-x 2 ec ec 4096 Jan  5 20:47 Pictures/
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Public/
drwxr-xr-x 3 ec ec 4096 Jan  5 15:16 snap/
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Templates/
drwxr-xr-x 2 ec ec 4096 Jan  4 19:54 Videos/

In contrast ls -alFd */ returns the same results as ll -d */

According to man ls the flag -F --classify append indicator (one of */=>@|) to entries.

I assume that because of the additional indicator set by -F, ll -d */ appends the forward slash although it's is unclear as the need or value of including the additional suffix i.e. why does it need to add another / if one already exists?

Secondly, is there a way to list directories only with ll -d */ without the extra /?

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Ryan
  • 177
  • 2
  • 8
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackexchange.com/rooms/103268/discussion-on-question-by-ryan-why-does-ll-d-result-in-an-additional-forward). – Jeff Schaller Jan 13 '20 at 20:08

2 Answers2

2

The list of files that are created with */ is generated by the shell. It is a list of directories with an / already appended:

$ echo */
Desktop/ Documents/ Downloads/ Music/ Pictures/ Public/ snap/ Templates/ Videos/

That is generated in one utility (the shell) and given to another utility (ls) for it to further resolve and process.

That is the list that ls gets. That's why you need the -d option to repeat the list without going inside each directory.

If you add a '-p' option to ls, it will append an additional / to each directory to indicate that it is a directory:

$ ls -pd */
Desktop//  Documents//  Downloads//  Music//  Pictures//  Public//  snap//  Templates//  Videos//

If the color option for ls is active you should see the pathname in one color and the / in another.

The -F ls option is similar to the -p option but it may also use other characters to signal other types of files (not only directories) with each character from this list: one of */=>@|

  • I am assuming that the `shell` is appending the forward slash as a result of the bit that identifies it as a directory i.e. `d` hence `echo */` returns the result `Desktop/`. If this is correct, it suggests (my interpretation) is that `ls -F` appends an additional forward slash as an indicator as does `-p`. I am unclear as why it would need to do this if the shell is already processing the bits. Equally, how can `ll -d */` be limited to only return a list of directories without the additional suffix? – Ryan Jan 13 '20 at 06:25
  • Why are you assuming that, when the trailing slash is _right there in your pattern_? – JdeBP Jan 13 '20 at 08:33
  • @JdeBP The usual problem when some syntax has **two** consequences is that "which one has precedence?". Like with a trailing `/`, it **both** selects only directories **and** appends an `*` to every entry. If only directories are listed why to append a trailing `/` to each entry? All are equal, there is no need to identify directories. If a trailing `/` means that a `/` should be appended, then, why only directories are listed. In any case, yes, the shell doesn't follow logic in many corner cases, so this is only one additional quirk, but the user has a valid point IMhO. Thanks. –  Jan 13 '20 at 15:06
  • @Ryan Yes, the shell adds what is is given, as in `echo ./////*` each entry is prepended with `./////`. In the same idea, a `echo ./*/` should have a trailing `/` (as given by who wrote the command). However, yes, it seems superfluous that `ls` adds **another** `/` to each entry. Yes, your interpretation is correct, `ls` appends an additional `/`. To *Return a list of directories without the additional suffix* you need to use something different than `ls` (or `ll`), try: `find * -prune -type d -ls` or: `ls -l * | grep '^d'` –  Jan 13 '20 at 15:48
  • @Isaac - Could you expand on `Yes, the shell adds what is is given, as in echo ./////* each entry is prepended with ./////. In the same idea, a echo ./*/ should have a trailing / (as given by who wrote the command).` as it isn't obvious to me? For example, under what circumstances would there be `echo ./////*`? – Ryan Jan 13 '20 at 16:59
  • @Ryan The set of reasons to write some path or other are outside this answer. For example. if the user wants to list files up two folders, he would write `echo ../../././*`, for example, in this case, the shell would prefix with `../../././` each file listed. Or, in some other (not so useful) instance, an user might write `echo /etc/////apache2/*`, in this case, each entry listed will start with `/etc/////apache2/`. Does it help? –  Jan 13 '20 at 17:28
  • @Isaac - It may be a deeper discussion since it isn't clear to me as the benefit of `echo ../../././*` and why not `echo ../*` assuming that the command isn't run from a child path e.g. / as opposed to /home/ec/? – Ryan Jan 14 '20 at 07:56
  • The problem with that whole argument is that it _does not_ have two consequences. It has one. It causes the expansion to separate pathname components at that point, resulting in post-expansion pathnames that have slashes in the same place. – JdeBP Jan 16 '20 at 01:12
  • @JdeBP I fail to follow what you mean. Separate?, Components? We are talking about the trailing slash(es), aren't we? –  Jan 16 '20 at 01:34
0

There a way to list directories only with ll -d */ without the extra /.

If you put following function in .bashrc, it will take effect after you do "unalias ll" or remove "alias ll" from .bashrc

function ll {
    local option=F OPTIND c
    while getopts d c; do
        case $c in
            d) option=$c;;
        esac
    done; shift "$((OPTIND - 1))"
    ls -la -$option "$@"
}
Philippe
  • 1,275
  • 7
  • 14
  • Does this mean that there is no way to limit the results without the additional forward slash? If yes, what value does the extra suffix provide that the single indicator doesn't? Secondly, is there a method other than introducing a function as it isn't likely to implement these across all the systems? – Ryan Jan 13 '20 at 06:53