Symbolic Links – Trailing Slashes on Symlinks to Directories

coreutilsdirectoryfilenamessymlink

I'm trying to emulate the process of path resolution (see man page path_resolution) in unix-like systems.

My OS is Linux with GNU coreutils 8.7.

In order to clarify the meaning of extra trailing '/' in resolution,
I did following things in a shell:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link

Everything was fine, because this_is_link is a symlink, and I just removed it away.
But while trying:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/

It echoed rm: cannot remove 'this_is_link/': Is a directory

Well, the trailing '/' caused following of symlink, I thought.
So, I tried another command: rmdir this_is_link/

And a funny result came out: rmdir: failed to remove 'this_is_link/': Not a directory

Not what I expected. So I asked my friend to confirm if the same result could be obtained on his system. He had a lower version of coreutils than I had. And the result was amazing, no matter rm or rmdir 'this_is_link/', the same error Not a directory occurs.

And another friend just tried it out on his Mac OS, the result is: rm => 'Is a directory', rmdir => the directory is successfully deleted, the link remained.

Are there any spec about the exact behavior of path resolution?

Best Answer

The POSIX/Single Unix specification specifies that a pathname with a trailing slash must refer to a directory (see base definitions ยง4.11 pathname resolution). foo/ is in fact defined as equivalent to foo/. (for path resolution purposes, not when manipulating file names; basename and dirname ignore trailing slashes). Most implementations respect this, but there are a few exceptions.

This explains the behavior of rm this_is_link/: it's equivalent to rm this_is_link/., where the argument is clearly a directory.

rmdir this_is_link/ should similarly refer to the directory. That it doesn't on your machine is a bug in GNU coreutils. OSX is behaving correctly here.

Related Question