For a much shorter version see the realpath function based on GNU readlink at the end.
Cf. also realpath command line utility for the Mac (C snippet; resolves Mac aliases as well) and Create & resolve Mac-type aliases from the command line.
function has_symlink() { declare basename path realpath path="${1}" [[ "${path}" == '/' ]] && return 1 #path="${path#/}" # trim a leading slash, if any #path="${path%/}" # trim a trailing slash, if any path="${path#"${path%%[!/]*}"}" # trim leading slashes, if any path="${path%"${path##*[!/]}"}" # trim trailing slashes, if any OIFS="${IFS}" IFS='/' for basename in $path; do realpath="${realpath%/}/${basename}" [[ -L "${realpath}" ]] && IFS="${OIFS}" && return 0 done IFS="${OIFS}" return 1 } function realpath() { declare basename currentpath optionstr path realpath declare -i var=0 if [[ "${1}" == '-n' ]]; then optionstr='-n'; shift; fi # default to the current working directory # cf. help pwd; type -a pwd; type -p pwd; type -P pwd path="${1:-$(pwd -P)}" if [[ "${path}" == '/' ]]; then if [[ "${optionstr}" == '-n' ]]; then printf "%s" "${path}" else printf "%s\n" "${path}" fi return 0 fi #path="${path#/}" # trim a leading slash, if any #path="${path%/}" # trim a trailing slash, if any path="${path#"${path%%[!/]*}"}" # trim leading slashes, if any path="${path%"${path##*[!/]}"}" # trim trailing slashes, if any OIFS="${IFS}" IFS='/' for basename in $path; do realpath="${realpath%/}/${basename}" if [[ "${realpath}" == '/' ]]; then break; fi realpath="${realpath%/}" # cf. http://www.commandlinefu.com/commands/view/2369/find-broken-symlinks-and-delete-them [[ -L "${realpath}" ]] && [[ -n "$(/usr/bin/find -L "${realpath}" -type l -maxdepth 0 -print 2>/dev/null)" ]] && echo "Broken symlink: ${realpath}" && return 1 [[ ! -e "${realpath}" ]] && echo "No such file or directory: ${realpath}" && return 1 [[ ! -L "${realpath}" ]] && realpath="${realpath}" && continue while [[ -L "${realpath}" ]]; do currentpath="${realpath}" realpath="$(/usr/bin/readlink "${realpath}")" [[ "${realpath}" == '/' ]] && continue realpath="${realpath%/}" done : <<-'COMMENT' while [[ -L "${realpath}" ]]; do currentpath="${realpath}" if [[ -d "${realpath}" ]]; then realpath="$(cd "${realpath}"; pwd -P)" else realpath="$(/usr/bin/readlink "${realpath}")" fi [[ "${realpath}" == '/' ]] && continue realpath="${realpath%/}" done COMMENT currentpath="${currentpath%/*}" # get dirname if [[ "${realpath}" == '/' ]]; then realpath='/' elif [[ "${realpath:0:1}" == '/' ]]; then realpath="${realpath}" else realpath="${currentpath}/${realpath}" fi done # for IFS="${OIFS}" # repeat the procedure if $realpath has a symbolic link element in it if has_symlink "${realpath}"; then if [[ "${optionstr}" == '-n' ]]; then realpath -n "${realpath}" var=1 else realpath "${realpath}" var=1 fi fi [[ $var -eq 1 ]] && return 0 if [[ "${optionstr}" == '-n' ]]; then printf "%s" "${realpath}" else printf "%s\n" "${realpath}" fi return 0 } realpath realpath -n cd /Volumes realpath cd /System/Library/Frameworks/Cocoa.framework/Headers realpath realpath /System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h realpath /dev/stdin realpath /dev/stdout realpath /dev/stderr realpath /network/Servers realpath /network/Library alias readlink='/usr/bin/readlink' alias gnureadlink='/usr/local/bin/gnureadlink' # cf. Compiling GNU coreutils on Mac OS X, # http://codesnippets.joyent.com/posts/show/1799 gnureadlink --help gnureadlink -f /System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h readlink /System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h realpath /System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h path='/System/Library/Frameworks/AddressBook.framework/AddressBook' path='/System/Library/Frameworks/Automator.framework/Versions/Current/Resources/Dutch.lproj/InfoPlist.strings' path="$(/usr/bin/find -x /Volumes -mindepth 1 -maxdepth 1 -type l -print | /usr/bin/head -n 1)" path='/System/Library/Frameworks/AudioToolbox.framework/Versions/A/Headers/AudioToolbox.h' path='/System/Library/Frameworks/AudioToolbox.framework/Versions/Current/Headers/AudioToolbox.h' readlink "${path}"; echo $? realpath "${path}"; echo $? gnureadlink -f "${path}"; echo $? realpath -n "${path}" # realpath function based on GNU readlink # cf. Compiling GNU coreutils on Mac OS X, # http://codesnippets.joyent.com/posts/show/1799 unset -f realpath function realpath() { /usr/local/bin/gnureadlink -f "${1}" return 0 } realpath "${path}"; echo $?
if [[ "${realpath}" == '/' ]]; then
realpath='/'
elif [[ "${realpath:0:1}" == '/' ]]; then
realpath="${realpath}"
else
realpath="${currentpath}/${realpath}"
fi
done # for
IFS="${OIFS}"
Outdoor Media | Corporate Identity