यह दक्षता के बारे में नहीं है - यह शुद्धता के बारे में है। 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/
।