আমি আর একটি বাস্তবায়ন দিয়ে গাদা করতে ঘৃণা করি, তবে আমার প্রয়োজন একটি) একটি বহনযোগ্য, খাঁটি শেল বাস্তবায়ন এবং খ) ইউনিট-পরীক্ষা কভারেজ , কারণ এর মতো কোনও কিছুর জন্য এজ-সংখ্যার সংখ্যা অ-তুচ্ছ ।
পরীক্ষা এবং সম্পূর্ণ কোডের জন্য গিথুবটিতে আমার প্রকল্প দেখুন । নিম্নলিখিতটি বাস্তবায়নের একটি সংক্ষিপ্তসার:
কীথ স্মিথ আশ্চর্যের সাথে উল্লেখ করেছেন, readlink -f
দুটি কাজ করেছেন: 1) প্রতীকগুলি পুনরাবৃত্তভাবে সমাধান করে এবং 2) ফলাফলটি স্বীকৃতি দেয়, তাই:
realpath() {
canonicalize_path "$(resolve_symlinks "$1")"
}
প্রথমত, সিমিলিংক রেজোলভার বাস্তবায়ন:
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
}
দ্রষ্টব্য যে এটি সম্পূর্ণ বাস্তবায়নের সামান্য সরলীকৃত সংস্করণ । সম্পূর্ণ বাস্তবায়ন সিমলিংক চক্রের জন্য একটি ছোট চেক যুক্ত করে , পাশাপাশি আউটপুটকে কিছুটা ম্যাসেজ করে।
অবশেষে, কোনও পথকে আকাঙ্ক্ষিত করার জন্য ফাংশন:
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")
}
এটিই কমবেশি। আপনার স্ক্রিপ্টে পেস্ট করার জন্য যথেষ্ট সহজ, তবে যথেষ্ট কৌশলযুক্ত যে আপনি যে কোনও কোডে আপনার ব্যবহারের ক্ষেত্রে ইউনিট পরীক্ষা না করে তার উপর নির্ভর করতে উন্মাদ হবেন।
readlink
একটি বিল্টিন বা বাহ্যিক আদেশ হতে পারে।