Yine başka bir uygulama ile uğraşmaktan nefret ediyorum, ancak a) taşınabilir, saf bir kabuk uygulamasına ve b) birim test kapsamına ihtiyacım vardı , çünkü böyle bir şey için uç vakaların sayısı önemsiz değildir .
Testler ve tam kod için Github'daki projeme bakın . Aşağıdakiler uygulamanın bir özetidir:
Keith Smith'in açıkça belirttiği gibi readlink -f, iki şey yapar: 1) sembolik bağlantıları yinelemeli olarak çözer ve 2) sonucu kanonikleştirir, dolayısıyla:
realpath() {
canonicalize_path "$(resolve_symlinks "$1")"
}
İlk olarak, symlink çözümleyici uygulaması:
resolve_symlinks() {
local dir_context path
path=$(readlink -- "$1")
if [ $? -eq 0 ]; then
dir_context=$(dirname -- "$1")
resolve_symlinks "$(_prepend_path_if_relative "$dir_context" "$path")"
else
printf '%s\n' "$1"
fi
}
_prepend_path_if_relative() {
case "$2" in
/* ) printf '%s\n' "$2" ;;
* ) printf '%s\n' "$1/$2" ;;
esac
}
Bunun tam uygulamanın biraz basitleştirilmiş bir sürümü olduğunu unutmayın . Tam uygulama, sembolik bağlantı döngüleri için küçük bir kontrol ekler , ayrıca çıktıya biraz masaj yapar.
Son olarak, bir yolu standartlaştırma işlevi:
canonicalize_path() {
if [ -d "$1" ]; then
_canonicalize_dir_path "$1"
else
_canonicalize_file_path "$1"
fi
}
_canonicalize_dir_path() {
(cd "$1" 2>/dev/null && pwd -P)
}
_canonicalize_file_path() {
local dir file
dir=$(dirname -- "$1")
file=$(basename -- "$1")
(cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file")
}
Aşağı yukarı bu kadar. Betiğinize yapıştıracak kadar basit, ancak kullanım durumlarınız için birim testleri olmayan herhangi bir koda güvenmek için çılgın olacağınız kadar zor.
readlinkbir yerleşik veya harici komut olabilir.