这不关乎效率,而是关乎正确性。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/