NB: In the original title of this post, I used the word standard in the everyday sense of "well-established" (and therefore time-tested, as a contrast to quick solutions I could roll myself). In the context of Unix-talk, however, the word standard has a very specific (and very different) technical meaning. This alternative, more correct, interpretation of the word standard in the title rendered the rest of my post inconsistent. (Thanks to Stéphane Chazelas for pointing this out.) Therefore, I've revised the title, replacing standard with tested.
As an example of the problem I refer to in the title, suppose I have the directory structure shown below
/tmp/example
├── a/
│ └── b/
│ └── c/
│ └── d/
│ └── target
└── A/
└── B/
├── C/
│ └── D/
│ └── symlink-0 -> ../../symlink-1/b/c/d/target
│
└── symlink-1 -> /tmp/example/a
Note that /tmp/example/A/B/C/D/symlink-0
is a symbolic link whose immediate target is a relative path:
$ readlink /tmp/example/A/B/C/D/symlink-0
../../symlink-1/b/c/d/target
I want to get the absolute path corresponding to this immediate target. IOW, I want to perform the partial resolution
/tmp/example/A/B/C/D/symlink-0 -> /tmp/example/A/B/symlink-1/b/c/d/target
Is there a standard (or at least well-established and time-tested) Unix utility to do this?
Note that readlink -f
resolves paths fully (to a symlink-free path); for the case discussed here, for example:
$ readlink -f /tmp/example/A/B/C/D/symlink-0
/tmp/example/a/b/c/d/target
This means that readlink -f
is not the answer to the question I'm asking here.
I could roll my own, by adding adequate error-checking, etc., to something like the following zsh
function:
canonicalize () {
local abspath=$(dirname $1)/$(readlink $1)
printf -- '%s\n' $abspath:a
}
...but I've learned (the hard way) not to underestimate the difficulty of implementing this sort of utility robustly, so I'd prefer to use existing tools, if possible.
FWIW, the script below generates this post's example:
mkdir -p /tmp/example/a/b/c/d /tmp/example/A/B/C/D
touch /tmp/example/a/b/c/d/target
ln -s /tmp/example/a /tmp/example/A/B/symlink-1
ln -s ../../symlink-1/b/c/d/target /tmp/example/A/B/C/D/symlink-0
readlink
norzsh
are standard utilities for instance.stable
package from http.us.debian.org/debian, it's "standard" enough for me. I.e. by "standard" I meant "well-established and time-tested".