![]() ![]() ![]() (Note that platforms that lack readlink may still provide other, non-POSIX methods for resolving a symlink e.g., Duffy mentions HP-UX's find utility supporting the %l format char. Otherwise, the output from ls -l is parsed, which is the only POSIX-compliant way to determine a symlink's target.Ĭaveat: this will break if a filename or path contains the literal substring -> - which is unlikely, however. If readlink is available, it is used (without options) - true on most modern platforms. For a version of this function that is itself written in POSIX-compliant shell code (for /bin/sh), see here. Note: The function is a bash function, and is POSIX-compliant only in the sense that only POSIX utilities with POSIX-compliant options are used. macOS uses an older version of the BSD implementation of readlink note that recent versions of FreeBSD/PC-BSD do support -f.ĭoes not even have readlink, but has POSIX-compatible utilities - e.g., HP-UX (thanks, Duffy).ĭefines helper shell function, rreadlink(), which resolves a given symlink to its ultimate target in a loop - this function is in effect a POSIX-compliant implementation of GNU readlink's -e option, which is similar to the -f option, except that the ultimate target must exist.Has a readlink utility, but lacks the -f option (in the GNU sense of resolving a symlink to its ultimate target) - e.g., macOS. If your script must run on any platform that: Multi-(Unix-like-)platform solution (including platforms with a POSIX-only set of utilities): Since the target by definition exists in this scenario, any of the 3 options can be used I've chosen -f here, because it is the most well-known one. Note that GNU readlink has 3 related options for resolving a symlink to its ultimate target's full path: -f ( -canonicalize), -e ( -canonicalize-existing), and -m ( -canonicalize-missing) - see man readlink. If your script needs to run on Linux only or you know that GNU readlink is in the $PATH, use readlink -f, which conveniently resolves a symlink to its ultimate target: scriptDir=$(dirname - "$(readlink -f - "$BASH_SOURCE")") This answer covers that case: a solution that also works when the script is invoked through a symlink or even a chain of symlinks: Konecny's answer provides an effective solution, but - as he mentions - it only works if the actual script is not invoked through a symlink residing in a different directory. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |