Perché le barre rovesciate sono incluse in questo script di shell?


21

Nella mia copia dello conda.shscript, vedo le seguenti righe:

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

Sono curioso di sapere perché c'è una barra rovesciata davanti al l' din dirname. Non credo sia necessario. Questo uso di barre rovesciate appare anche in altri punti del file sorgente. C'è un motivo per farlo che mi manca?


Risposte:


30

La barra rovesciata sopprimerà l'espansione dell'alias, ovvero esegue il comando originale e si assicura che la versione alias non venga eseguita. Gli script possono essere eseguiti inconsapevolmente con l'espansione dell'alias quando il sistema è stato impostato shopt -s expand_aliases(solo BASH) o se viene eseguito utilizzando source.

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

Ad alcuni amministratori di sistema piace inserire una barra rovesciata in tutto come misura preventiva contro gli effetti collaterali degli alias, nel caso in cui sia stato aliasato involontariamente da qualche altra parte e l'alias viene espanso come spiegato in precedenza. Ad esempio, se il sistema lo ha impostato alias dirname='dirname -z'da qualche parte e la condizione consente l'espansione dell'alias, sfortunatamente verrà dirname -zinvece chiamato uno script che tenta di chiamare dirname , che non era lo script previsto.

Se c'è la certezza che tale alias non esiste, possiamo rimuovere tutta la barra rovesciata e dovrebbe funzionare bene.

In alternativa, è possibile utilizzare commandinvece della versione con barra rovesciata per sopprimere l'alias. Pertanto, invece di \dirname, si può usare command dirname, che potrebbe sembrare più leggibile. (Per comandi integrati come cd, si dovrebbe usare builtininvece). Preferisco questo invece, poiché ignora anche la funzione con lo stesso nome e tutti gli alias.


1
Vale anche la pena notare unalias -ache rimuove tutti gli alias.
Centimane,

19
@Centimane Sì, ma assicurati di fare \unalias -aper sopprimere l'espansione dell'alias
Ben C

Potrebbe anche aver scritto l'amministratore di sistema /usr/bin/dirname?
RonJohn,

@RonJohn Sì, avrebbe potuto in questo caso particolare. Tuttavia, per alcuni programmi distribuzioni diverse le inseriscono in directory diverse. Un'istanza che viene in mente è /bin/edsu Ubuntu vs /usr/bin/edsu CentOS. Inserire un percorso completo rende lo script meno portatile.
doneal24

@ doneal24 che ne dici di qualcosa del genere DIRNAME=$(which dirname), dal momento whichche non vede alias?
RonJohn,

20

Se si conda.shtratta di un file destinato a essere di provenienza, le barre rovesciate servono per bypassare gli alias. Bash disabilita in genere l'espansione dell'alias per l'esecuzione di script, ma per i file di origine, che possono essere eseguiti in shell interattive, non è così. Quindi è dirnamepossibile eseguire un alias denominato dirname, ma \dirnamesalterà l'espansione dell'alias ed eseguirà una funzione o un comando denominato dirname. (Non solo barre rovesciate, tuttavia, qualsiasi quotazione farà.)


5
Or command dirname.
Kusalananda

7
( \command dirname, nel caso in cui qualcuno abbia anche creato un alias command.): |
Muru,

Perché ignora gli alias? Questa funzionalità è un caso speciale di qualcosa o doveva essere codificata in bash (ovvero un hack)?
extremeaxe5,

@ extremeaxe5 bash non fa l'espansione dell'alias se (qualsiasi parte di) la parola viene citata.
Muru,

1
@ extremeaxe5 se ti chiedi perché la funzione esiste, non lo so. È nello standard POSIX tuttavia: "la parola del nome del comando [...] deve essere esaminata per determinare se si tratta di un nome alias non quotato e valido"
muru
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.