realpath.bash
1 #!/usr/bin/env bash 2 3 # Based on realpath.sh written by Michael Kropat 4 # Found at: https://github.com/mkropat/sh-realpath/blob/65512368b8155b176b67122aa395ac580d9acc5b/realpath.sh 5 6 bash_realpath() { 7 canonicalize_path "$(resolve_symlinks "$1")" 8 } 9 10 resolve_symlinks() { 11 _resolve_symlinks "$1" 12 } 13 14 _resolve_symlinks() { 15 _assert_no_path_cycles "$@" || return 16 17 local dir_context path 18 if path=$(readlink -- "$1"); then 19 dir_context=$(dirname -- "$1") 20 _resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@" 21 else 22 printf '%s\n' "$1" 23 fi 24 } 25 26 _prepend_dir_context_if_necessary() { 27 if [ "$1" = . ]; then 28 printf '%s\n' "$2" 29 else 30 _prepend_path_if_relative "$1" "$2" 31 fi 32 } 33 34 _prepend_path_if_relative() { 35 case "$2" in 36 /* ) printf '%s\n' "$2" ;; 37 * ) printf '%s\n' "$1/$2" ;; 38 esac 39 } 40 41 _assert_no_path_cycles() { 42 local target path 43 44 target=$1 45 shift 46 47 for path in "$@"; do 48 if [ "$path" = "$target" ]; then 49 return 1 50 fi 51 done 52 } 53 54 canonicalize_path() { 55 if [ -d "$1" ]; then 56 _canonicalize_dir_path "$1" 57 else 58 _canonicalize_file_path "$1" 59 fi 60 } 61 62 _canonicalize_dir_path() { 63 (cd "$1" 2>/dev/null && pwd -P) 64 } 65 66 _canonicalize_file_path() { 67 local dir file 68 dir=$(dirname -- "$1") 69 file=$(basename -- "$1") 70 (cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file") 71 }