4

When executing a "long" listing of a soft link, ls -l displays the file attributes of the soft link. When executing ls -lL (or ls -l --dereference), the file attributes are those of the file that the link points to, but ls still prints the name of the link itself. The man page doesn't say anything about this. The info page on ls just says that "ls still prints the name of the link itself, not the name of the file that the link points to.", without an explanation as to the reason why. I suppose this is a deliberate choice, but does anyone know the rationale behind this behavior of ls -L?

8

Because the filename at the other end of the link is not (or might not be) the filename in the directory that you're accessing with ls.

Two problems with displaying the name of the target of the symbolic link in place of the name of the link itself:

  1. The file does not exist. If the name of target of the symbolic link is displayed in the directory listing, you may be led to believe that this is the name of the file in that directory, but it isn't. The name of the target is not the name by which you access the file in that directory; the file with that filename does not exist (in that directory), or, in the worst case, it may be a totally different file (or a directory, or whatever) when accessed by that name.

  2. Files may appear to have identical names. If the name of the target of the symbolic link is displayed, then you may find that it's exactly identical to another filename in that directory, which can not be true on a Unix system.

In these cases, it leads to confusion for the users, and they would have to verify the listing by using ls without -L, which would render the -L option pretty pointless.

This (not displaying the name of the target) is also the behaviour specified by POSIX, quite explicitly:

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

There is no further discussion about this in the Rationale section of the POSIX ls manual.

  • The POSIX passage you mention is indeed clear on the matter, thanks for adding that. But could you explain your first sentence please? Wouldn't something like that be a broken link? – twan163 Jan 2 '17 at 21:02
  • @twan163 I've updated my answer. – Kusalananda Jan 2 '17 at 21:08
  • @Kusalananda: ls prints the nam of the file which you requested, or the names of the files in the directory that you requested. Why on earth would it print the nane of another file or of files in another directory? – AlexP Jan 2 '17 at 21:09
  • @AlexP Exactly. – Kusalananda Jan 2 '17 at 21:11
  • @twan163: So? "Broken" links can still be useful. E.g. the fnord webserver uses them for HTTP re-directs. Basically, if you want to configure your /search URI to redirect to Google, you just do ln -s http://www.google.com /var/www/search. In which case you probably want to have the file listed as search and not http://www.google.com. – Jörg W Mittag Jan 3 '17 at 0:12
2

The rationale for symbolic links to keep showing the link name and not the linked to file name when the -L or -H options are used is consistency.

A notable difference between symbolic links and hard links is that when listed with ls -l, the permissions of a symbolic links are of little use (outside the initial s) and the filename is showing both the link name and the linked to pathname using the convention symlink -> target. The rationale of this behavior is this ls -l command works regardless of whether the target exists or not. Its role is to provide information about the symbolic link itself.

The -L option has been added to allow a behavior similar to what happens with a hard link. The file permissions are the actual ones, i.e. the ones of the underlying inode, and the filename is the one that is being queried, not something else. That would be confusing if you run for example ls -lL a* and filenames not starting with an a would be displayed. Moreover, if the target link doesn't exist, there are no permissions to display because there is no underlying inode, and the ls -lL command fails in error.

Another good reason explaining why it is done that way is that a symbolic link is often associated with a relative or an absolute path, not a single filename but there is no provision to display a relative or full path with ls -l, only plain filenames with no slashes or dot dot…

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.