Estoy probando shellcheck .
Tengo algo asi
basename "${OPENSSL}"
y recibo la siguiente sugerencia
Use parameter expansion instead, such as ${var##*/}.
Desde el punto de vista práctico no veo diferencia
$ export OPENSSL=/opt/local/bin/openssl
$ basename ${OPENSSL}
openssl
$ echo ${OPENSSL##*/}
openssl
Como basenameestá en las especificaciones POSIX , no sé por qué debería ser la mejor práctica. Alguna pista?

csh. Supongocshque no es POSIX entonces.Respuestas:
No se trata de eficiencia, se trata de corrección.
basenameusa líneas nuevas para delimitar los nombres de archivo que imprime. En el caso habitual, cuando solo pasa un nombre de archivo, agrega una nueva línea final a su salida. Dado que los nombres de archivo pueden contener nuevas líneas, esto dificulta el manejo correcto de estos nombres de archivo.Se complica aún más por el hecho de que la gente utiliza generalmente
basenamecomo esto:"$(basename "$file")". Esto hace que las cosas aún más difícil, porque$(command)tiras todos los saltos de línea finales decommand. Considere el caso poco probable que$filetermina con una nueva línea. Luegobasenameagregará una nueva línea adicional, pero"$(basename "$file")"eliminará ambas líneas nuevas, dejándolo con un nombre de archivo incorrecto.Otro problema
basenamees que si$filecomienza con un-(guión aka menos), se interpretará como una opción. Este es fácil de arreglar:$(basename -- "$file")La forma robusta de usar
basenamees esta:Una alternativa es usarla
${file##*/}, que es más fácil pero tiene errores propios. En particular, está mal en los casos donde$filees/ofoo/.fuente
$filees asífoo/? ¿Y si es así/?basenameenfoque es mejor, después de todo, tan hacky como es. Las mejores alternativas que se me ocurren son${${${file}%%/#}##*/}y[[ $file =~ "([^/]*)/*$" ]] && printf "%s" $match[1], las cuales son específicas de zsh y ninguna de las cuales se maneja/correctamente.Las líneas relevantes en
shellcheckel código fuente son:No se proporciona ninguna explicación explícitamente, pero según el nombre de la función (
checkNeedlessCommands) parece que @jordanm tiene toda la razón y sugiere que evite bifurcar un nuevo proceso.fuente
dirname,basename,readlinkEtc (gracias @Marco - esto se corrige) pueden crear problemas de portabilidad cuando la seguridad se vuelve importante (que requiere la seguridad de la ruta). Muchos sistemas (como Fedora Linux) lo ubican/binmientras que otros (como Mac OSX) lo ubican/usr/bin. Luego está Bash en Windows, por ejemplo, cygwin, msys y otros.Siempre es mejor mantenerse puro Bash, cuando sea posible.(por comentario de @Marco)Por cierto, gracias por el puntero para comprobar, no he visto eso antes.
fuente
dirnameen absoluto. 3) Las utilidades básicas básicas deben estar en la RUTA, donde sea que estén almacenadas. Todavía no he visto un sistema dondebasenameno estaba en la RUTA. 4) Asumir que bash está disponible es un problema de portabilidad. Siempre es mejor mantenerse alejado de bash y usar un shell POSIX cuando se requiere portabilidad.posixy nobash. No encuentro ningún indicador de que el OP requiera una solución bash. Su afirmación "Siempre es mejor mantenerse puro Bash" es simplemente incorrecta, lo siento.