Não se trata de eficiência - é de correção. basenameusa novas linhas para delimitar os nomes de arquivos impressos. No caso usual, quando você passa apenas um nome de arquivo, ele adiciona uma nova linha à sua saída. Como os nomes de arquivos podem conter novas linhas, isso dificulta o tratamento correto desses nomes de arquivo.
É ainda mais complicada pelo fato de que as pessoas geralmente usam basenamecomo este: "$(basename "$file")". Isso torna as coisas ainda mais difíceis, porque $(command)retira todas as novas linhas finais command. Considere o caso improvável que $filetermina com uma nova linha. Em seguida, basenameirá adicionar uma nova linha extra, mas "$(basename "$file")"irá retirar as duas novas linhas, deixando-o com um nome de arquivo incorreto.
Outro problema basenameé que, se $filecomeçar com um -(traço aka menos), ele será interpretado como uma opção. Este é fácil de corrigir:$(basename -- "$file")
A maneira robusta de usar basenameé esta:
# 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%??}"
Uma alternativa é usar ${file##*/}, o que é mais fácil, mas possui bugs próprios. Em particular, está errado nos casos em que $fileé /ou foo/.