¿Por qué se incluyen las barras invertidas en este script de shell?

21

En mi copia del conda.shguión, veo las siguientes líneas:

if [ -n "${_CE_CONDA}" ] && [ -n "${WINDIR+x}" ]; then
    SYSP=$(\dirname "${CONDA_EXE}")
else
    SYSP=$(\dirname "${CONDA_EXE}")
    SYSP=$(\dirname "${SYSP}")
fi

Soy curioso en cuanto a por qué hay una barra invertida delante del el den dirname. No creo que sea necesario. Este uso de barras invertidas también aparece en otros lugares en el archivo fuente. ¿Hay alguna razón para hacer esto que me falta?

extremeaxe5
fuente

Respuestas:

30

La barra invertida suprimirá la expansión de alias, es decir, ejecuta el comando original y se asegura de que la versión de alias no se ejecute. Los scripts pueden ejecutarse sin saberlo con expansión de alias cuando el sistema se ha configurado shopt -s expand_aliases(solo BASH) o si se ejecuta utilizando source.

./conda.sh          # usually no alias expansion (unless `shopt -s expand_aliases` in BASH)
source ./conda.sh   # alias expansion
. ./conda.sh        # alias expansion

A algunos administradores de sistemas les gusta poner una barra invertida en todo como medida preventiva contra los efectos secundarios de los alias, solo en caso de que se haya alias involuntariamente en otro lugar y el alias se expanda como se explicó anteriormente. Por ejemplo, si el sistema ha configurado esto en alias dirname='dirname -z'algún lugar y la condición permite que el alias se expanda, entonces un script que intenta llamar a dirname desafortunadamente llamará dirname -z, que no era el script previsto.

Si hay certeza de que dicho alias no existe, podemos eliminar toda la barra invertida y debería funcionar bien.

Alternativamente, se puede usar en commandlugar de la versión de barra diagonal inversa para suprimir el alias. Por lo tanto, en lugar de \dirname, uno puede usar command dirname, lo que podría parecer más legible. (Para comandos integrados como cd, uno debería usar builtinen su lugar). Prefiero esto en su lugar, ya que también omite la función con el mismo nombre, así como cualquier alias.

otter.pro
fuente
1
También vale la pena señalar unalias -aque elimina todos los alias.
Centimane
19
@Centimane Sí, pero asegúrese de hacerlo \unalias -apara suprimir la expansión de alias
Ben C
¿Podría el administrador de sistemas también haber escrito /usr/bin/dirname?
RonJohn
@RonJohn Sí, podría haberlo hecho en este caso particular. Sin embargo, para algunos programas, diferentes distribuciones los colocan en diferentes directorios. Una instancia que viene a la mente es /bin/edUbuntu vs /usr/bin/edCentOS. Poner una ruta completa hace que el script sea menos portátil.
doneal24
@ doneal24 ¿qué pasa con algo así DIRNAME=$(which dirname), ya whichque no ve alias?
RonJohn
20

Si se conda.shtrata de un archivo de origen, las barras invertidas son para omitir los alias. Bash normalmente deshabilita la expansión de alias para la ejecución del script, pero para los archivos de origen, que pueden ejecutarse en shells interactivos, ese no es el caso. Por lo tanto, dirnamepuede ejecutar un alias llamado dirname, pero \dirnameomitirá la expansión del alias y ejecutará una función o comando llamado dirname. (No solo las barras invertidas, sin embargo, cualquier cita servirá).

muru
fuente
55
O command dirname.
Kusalananda
77
( \command dirname, en caso de que alguien también haya creado un alias command): |
Muru
¿Por qué evita los alias? ¿Es esta funcionalidad un caso especial de algo, o tuvo que ser codificado en bash (es decir, un hack)?
extremeaxe5
@ extremeaxe5 bash no hace expansión de alias si se cita (alguna parte de) la palabra.
Muru
1
@ extremeaxe5 si está preguntando por qué existe la función, no lo sé. Sin embargo, está en el estándar POSIX : "la palabra del nombre del comando [...] se examinará para determinar si es un nombre de alias válido sin comillas "
muru