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