Por que as barras invertidas estão incluídas neste script de shell?

21

Na minha cópia do conda.shscript, vejo as seguintes linhas:

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

Estou curioso para saber porque é que há uma barra invertida na frente do a dno dirname. Não acredito que seja necessário. Esse uso de barras invertidas também aparece em outros lugares no arquivo de origem. Existe uma razão para fazer isso que estou perdendo?

extremeaxe5
fonte

Respostas:

30

A barra invertida suprimirá a expansão do alias, ou seja, ele executa o comando original e garante que a versão do alias não seja executada. Os scripts podem ser executados sem saber com expansão de alias quando o sistema tiver definido shopt -s expand_aliases(apenas BASH) ou se for executado usando source.

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

Alguns administradores de sistema gostam de colocar barra invertida em tudo como uma medida preventiva contra os efeitos colaterais de aliases, apenas no caso de ter sido aliasado acidentalmente em outro lugar e o alias ser expandido conforme explicado anteriormente. Por exemplo, se o sistema definiu isso em alias dirname='dirname -z'algum lugar e a condição permite que o alias seja expandido, um script que tenta chamar dirname infelizmente chamará dirname -z, mas esse não foi o script pretendido.

Se houver certeza de que esse alias não existe, podemos remover toda a barra invertida e deve funcionar bem.

Como alternativa, pode-se usar em commandvez da versão de barra invertida para suprimir o alias. Assim, em vez de \dirname, pode-se usar command dirname, o que pode parecer mais legível. (Para comandos internos como cd, deve-se usar builtin). Em vez disso, prefiro isso, pois também ignora a função com o mesmo nome e com qualquer apelido.

otter.pro
fonte
1
Também vale a pena notar unalias -a, que remove todos os aliases.
Centimane 12/06
19
@Centimane Sim, mas certifique-se de \unalias -asuprimir a expansão de alias
Ben C
O administrador do sistema também poderia ter escrito /usr/bin/dirname?
RonJohn 13/06
@ RonJohn Sim, ele poderia ter neste caso particular. No entanto, para alguns programas, distribuições diferentes os colocam em diretórios diferentes. Uma instância que vem à mente é /bin/edno Ubuntu vs /usr/bin/edno CentOS. Colocar um caminho completo torna o script menos portátil.
doneal24 13/06
@ doneal24 que tal algo como DIRNAME=$(which dirname), uma vez whichque não vê aliases?
RonJohn 13/06
20

Se conda.shé um arquivo que deve ser originado, as barras invertidas servem para ignorar aliases. O Bash normalmente desativa a expansão de alias para execução de script, mas para arquivos de origem, que podem ser executados em shells interativos, esse não é o caso. Portanto, apenas dirnamepode executar um alias nomeado dirname, mas \dirnameignorará a expansão do alias e executará uma função ou comando nomeado dirname. (Porém, não apenas barras invertidas, qualquer citação serve.)

muru
fonte
5
Or command dirname.
Kusalananda
7
( \command dirname, apenas no caso de alguém também ter feito um pseudônimo command.): |
muru 12/06
Por que ignora aliases? Essa funcionalidade é um caso especial de alguma coisa ou precisou ser codificada no bash (ou seja, um hack)?
extremeaxe5 12/06
@ extremeaxe5 bash não faz expansão de alias se (qualquer parte) a palavra for citada.
muru 12/06
1
@ extremeaxe5 se você está perguntando por que o recurso existe, eu não sei. No entanto, ele está no padrão POSIX : "a palavra do nome do comando [...] deve ser examinada para determinar se é um nome de alias válido e não
citado