ฉันเกลียดไปกองกับการดำเนินงานยังอีก แต่ผมจำเป็นต้องมี) แบบพกพา, การดำเนินเปลือกบริสุทธิ์และ b) ความคุ้มครองหน่วยทดสอบเป็นจำนวนขอบกรณีสำหรับบางสิ่งบางอย่างเช่นนี้ไม่น่ารำคาญ
ดูโครงการของฉันบน Githubสำหรับการทดสอบและรหัสเต็ม สิ่งต่อไปนี้เป็นบทสรุปของการใช้งาน:
ในขณะที่ Keith Smith ชี้ให้เห็นอย่างชาญฉลาดreadlink -f
ทำสองสิ่ง: 1) แก้ไข symlink แบบวนซ้ำและ 2) ยอมรับผลลัพธ์ดังนี้:
realpath() {
canonicalize_path "$(resolve_symlinks "$1")"
}
ก่อนการใช้งานตัวแก้ไข symlink:
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
}
ทราบว่านี้เป็นรุ่นที่ง่ายขึ้นเล็กน้อยจากการดำเนินงานเต็มรูปแบบ การใช้งานเต็มรูปแบบเพิ่มการตรวจสอบขนาดเล็กสำหรับรอบ symlinkรวมถึงการนวดผลลัพธ์เล็กน้อย
ในที่สุดฟังก์ชั่นสำหรับ canonicalizing เส้นทาง:
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
อาจเป็นคำสั่งในตัวหรือภายนอก