Pourquoi les barres obliques inverses sont-elles incluses dans ce script shell?

21

Dans ma copie du conda.shscript, je vois les lignes suivantes:

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

Je suis curieux de savoir pourquoi il y a une barre oblique inverse devant le la ddans dirname. Je ne pense pas que ce soit nécessaire. Cette utilisation de barres obliques inverses apparaît également à d'autres endroits du fichier source. Y a-t-il une raison pour laquelle je manque cela?

extremeaxe5
la source

Réponses:

30

La barre oblique inverse supprimera l'expansion d'alias, c'est-à-dire qu'elle exécute la commande d'origine et s'assure que la version d'alias ne s'exécute pas. Les scripts peuvent s'exécuter sans le savoir avec une extension d'alias lorsque le système est défini shopt -s expand_aliases(BASH uniquement) ou s'il est exécuté à l'aide de source.

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

Certains administrateurs système aiment mettre une barre oblique inverse dans tout comme mesure préventive contre les effets secondaires des alias, juste au cas où ils seraient aliasés involontairement ailleurs et l'alias est développé comme expliqué précédemment. Par exemple, si le système a défini cela alias dirname='dirname -z'quelque part et que la condition autorise l'extension de l'alias, un script qui tente d'appeler dirname appellera malheureusement à la dirname -zplace, ce qui n'était pas le script prévu.

S'il est certain que de tels alias n'existent pas, nous pouvons supprimer toutes les barres obliques inverses et cela devrait fonctionner correctement.

Alternativement, on peut utiliser commandau lieu de la version barre oblique inverse pour supprimer l'alias. Ainsi, au lieu de \dirname, on peut utiliser command dirname, ce qui pourrait sembler plus lisible. (Pour les commandes intégrées comme cd, on devrait utiliser à la builtinplace). Je préfère cela à la place, car il contourne également la fonction du même nom ainsi que tous les alias.

otter.pro
la source
1
A noter également unalias -a, qui supprime tous les alias.
Centimane
19
@Centimane Oui, mais assurez-vous de \unalias -asupprimer l'expansion des alias
Ben C
Le sysadmin aurait-il pu également écrire /usr/bin/dirname?
RonJohn
@RonJohn Oui, il aurait pu le faire dans ce cas particulier. Cependant, pour certains programmes, différentes distributions les placent dans des répertoires différents. Un exemple qui me vient à l'esprit est /bin/edsur Ubuntu vs /usr/bin/edsur CentOS. Mettre un chemin complet rend le script moins portable.
doneal24
@ doneal24 qu'en est-il de quelque chose comme DIRNAME=$(which dirname), car whichne voit pas d'alias?
RonJohn
20

Si conda.shun fichier est censé provenir, les barres obliques inverses sont destinées à contourner les alias. Bash désactive généralement l'expansion d'alias pour l'exécution de script, mais ce n'est pas le cas pour les fichiers d'origine, qui peuvent s'exécuter dans des shells interactifs. Il suffit donc dirnamed'exécuter un alias nommé dirname, mais d' \dirnameignorer l'expansion d'alias et d'exécuter une fonction ou une commande nommée dirname. (Pas seulement des contre-obliques, cependant, toute citation fera l'affaire.)

muru
la source
5
Ou command dirname.
Kusalananda
7
( \command dirname, au cas où quelqu'un aurait également créé un alias command.): |
muru
Pourquoi contourne-t-il les alias? Cette fonctionnalité est-elle un cas particulier de quelque chose, ou devait-elle être codée en dur dans bash (c'est-à-dire un hack)?
extremeaxe5
@ extremeaxe5 bash ne fait pas d'extension d'alias si (n'importe quelle partie de) le mot est cité.
muru
1
@ extremeaxe5 si vous demandez pourquoi la fonctionnalité existe, je ne sais pas. Il est cependant dans la norme POSIX : "le mot du nom de la commande [...] doit être examiné pour déterminer s'il s'agit d'un nom d'alias valide non cité "
muru