Bash – What’s the difference between `-h` and `-L` in bash conditional expressions

bashshelltest

According to the man page:

       -h file
              True if file exists and is a symbolic link.
    ...
       -L file
              True if file exists and is a symbolic link.

They both seem to say the exact same thing, but then why two separate flags? Are reasons of historical compatibility? Some subtle difference across versions of bash? Something else?

Best Answer

There is no difference whatsoever. The POSIX description of both options reads

True if pathname resolves to an existing directory entry for a symbolic link. False if pathname cannot be resolved, or if pathname resolves to an existing directory entry for a file that is not a symbolic link. If the final component of pathname is a symbolic link, that symbolic link is not followed.

As you say, the reason to have both is most likely to support the most common choices made by historical implementations of the test and [ utilities.

As for the test and [ built-in utilities of bash, they both functions the same, and have always done. The oldest available bash source in the current Git repository has the same wording for both (release 2.04, from 1991).

In the actual 1991 implementation, there's even a comment:

    case 'L':           /* Same as -h  */
    case 'h':           /* File is a symbolic link? */