In zsh, I make a symbolic link

$ ln -s ~/Documents symboliclink

and then I want to know what's inside this symbolic link.

$ ls -l symboliclink
> lrwxrwxrwx 1 user user 21 Oct 10 15:56 symboliclink -> /home/user/Documents

This shows only the symbolic link, not what's inside it. If i use ls only, it lists the contents, but if I used the -l flag, it doesn't. This works in bash both for ls and ls -l. How can I get that behavior in zsh as well?

  • Why the downvote? – pfnuesel Oct 11 '16 at 7:28
  • I received 4 excellent answers and I had to pick one as a solution. If I could, I would pick all 4 as solutions. – pfnuesel Oct 11 '16 at 7:35

One likely cause for the seeming difference in the output of ls -l between zsh and bash is the use of Tab-completion with AUTO_REMOVE_SLASH enabled in zsh (which is the default).


When the last character resulting from a completion is a slash and the next character typed is a word delimiter, a slash, or a character that ends a command (such as a semicolon or an ampersand), remove the slash.

When typing ls -l symbTab, both zsh and bash will complete this to ls -l symboliclink/ (note the / at the end). The difference is that zsh (with enabled AUTO_REMOVE_SLASH) will remove the slash, if you just press Enter (i.e. end the command) there.

So you will effectively run ls -l symboliclink/ in bash, which tells ls -l to look behind the link. But in zsh you will run ls -l symboliclink, which tells ls -l that you want to see the information about the link and not the target directory.

ls without option -l will always show the contents of the target directory, regardless of there being an / at the end or not.

In order to get zsh to not remove the slash at the end, it is sufficient to just type it explicitly after TAB-completion. Usually this will not visibly change the completed text, but if you type a space or confirm the command, the / will remain. "Usually" because it is possible to set a highlighting for automatically added suffix characters, for example magenta and bold:


(Note: this may not work when using the external ZSH Syntax Highlighting plugin)

Another solution is (obviously) to disable AUTO_REMOVE_SLASH. This can be done with

setopt noautoremoveslash

This is ls option -H:

ls -lH  symboliclink

From man 1p ls:


If a symbolic link referencing a file of type directory is specified on the command line, ls shall evaluate the file information and file type to be those of the file referenced by the link, and not the link itself; however, ls shall write the name of the link itself and not the file referenced by the link.

Also note option -L


Evaluate the file information and file type for all symbolic links (whether named on the command line or encountered in a file hierarchy) to be those of the file referenced by the link, and not the link itself; however, ls shall write the name of the link itself and not the file referenced by the link. When -L is used with -l, write the contents of symbolic links in the long format (see the STDOUT section).


Simply add a '/' at the end.

ls -l symboliclink/
  • I'm curious if that is documented somewhere or just behavior you noticed? – MikeA Oct 10 '16 at 16:02

The behavior of the ls program does not depend on the shell that calls it. If you observe different behavior with ls in bash and in zsh, it's because you have an alias (or function) called ls in one of the shells but not in the other. The behavior you're observing in zsh corresponds to what ls does, so you must be calling it with additional options in bash.

You may have aliased ls to ls -H or ls -L, to make it dereference symbolic links. This is a bad idea because you then can't get information about the symlinks themselves, other than by bypassing the alias (\ls).

When a file is a symbolic link to a directory, you can act on the directory rather than the file by adding a slash at the end: ls -l symboliclink/ is equivalent to ls -l symboliclink/.. See When is a symlink treated as the thing it links to, and as a symlink?

  • Though your observations are correct, I do not have an alias set. The difference is that when I do ll symbol and then hit Tab, bash autocompletes to ll symboliclink/, while zsh autocompletes to ll symboliclink. Thanks for the clarifications, though. +1 – pfnuesel Oct 11 '16 at 7:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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