มันไม่เกี่ยวกับประสิทธิภาพ - แต่เกี่ยวกับความถูกต้อง basename
ใช้การขึ้นบรรทัดใหม่เพื่อกำหนดขอบเขตชื่อไฟล์ที่พิมพ์ออกมา ในกรณีปกติเมื่อคุณส่งชื่อไฟล์เพียงไฟล์เดียวมันจะเพิ่มบรรทัดใหม่ต่อท้ายไปยังเอาต์พุต เนื่องจากชื่อไฟล์อาจมีการขึ้นบรรทัดใหม่ด้วยตนเองจึงทำให้ยากต่อการจัดการชื่อไฟล์เหล่านี้อย่างถูกต้อง
มันซับซ้อนมากขึ้นโดยความจริงที่คนมักจะใช้เช่นนี้basename
"$(basename "$file")"
สิ่งนี้ทำให้ยิ่งยากมากขึ้นเพราะ$(command)
แถบทุกcommand
บรรทัดใหม่ต่อท้ายจาก พิจารณากรณีที่ไม่น่า$file
จะจบลงด้วยการขึ้นบรรทัดใหม่ จากนั้นbasename
จะเพิ่มบรรทัดใหม่พิเศษ แต่"$(basename "$file")"
จะตัดการขึ้นบรรทัดใหม่ทั้งสองทำให้คุณมีชื่อไฟล์ไม่ถูกต้อง
อีกปัญหาหนึ่งbasename
คือถ้า$file
เริ่มต้นด้วย-
(ขีดหรือลบด้วยเครื่องหมายลบ) ก็จะถูกตีความเป็นตัวเลือก อันนี้ง่ายต่อการแก้ไข:$(basename -- "$file")
วิธีที่แข็งแกร่งในการใช้basename
คือ:
# A file with three trailing newlines.
file=$'/tmp/evil\n\n\n'
# Add an 'x' so we can tell where $file's newlines end and basename's begin.
file_x="$(basename -- "$file"; printf x)"
# Strip off two trailing characters: the 'x' added by us and the newline added by basename.
base="${file_x%??}"
อีกทางเลือกหนึ่งคือการใช้งาน${file##*/}
ซึ่งง่ายกว่า แต่มีข้อบกพร่องของตนเอง โดยเฉพาะอย่างยิ่งมันผิดในกรณีที่$file
เป็นหรือ/
foo/