Comment forcer un mot Bash à référencer un alias, une fonction, un fichier, etc.?

13

En essayant d'ajouter un peu plus de détails à une question connexe , j'ai réalisé que je ne sais pas comment spécifier lequel des types de mots Bash disponibles exécuter. Selon help typeil existe cinq types de mots:

  • alias
  • mot-clé
  • une fonction
  • intégré
  • fichier

Il est possible qu'un mot ait plusieurs types ( truen'est qu'un exemple; un mot plus souvent remplacé serait cd):

$ type -a true
true is a shell builtin
true is /bin/true

Comment forcez-vous l'exécution d'un synonyme spécifique? Jusqu'à présent, par ordre de priorité:

  • alias: Ceci est un cas particulier car il a priorité sur tous les autres synonymes. Le forcer ne serait utile que lorsque la commande échouerait si l'alias n'est pas défini.

    $ 
  • mot-clé:

    $ 
  • une fonction:

    $ 
  • intégré:

    $ builtin true
  • fichier:

    $ command true
    $ $(which true)
    $ /bin/true

Solutions partielles :

  • Citer un mot exclut les alias et les mots clés. C'est,

    $ 'true'

    exécutera uniquement la fonction, intégrée ou fichier.

l0b0
la source

Réponses:

10

Ce que vous demandez n'a pas vraiment de sens.

mot-clé signifie que c'est un mot qui fait partie de la syntaxe du shell. Ceux-ci sont reconnus par la tokenisation. Les citer suffit pour que le shell cesse de reconnaître.

Il est cependant possible d'alias un mot-clé dans la plupart des shells. Ainsi, les alias ont priorité sur les mots clés (en fait, ils sont développés tôt, et il y a plus de tokenisation après cela où vous pouvez avoir plus d'alias, de mots clés) ...

alias (à l'exception des alias zsh définis avec alias -gne sont développés qu'en position de commande), donc généralement pas dans builtin the-alias.

les fonctions ont la priorité sur les commandes intégrées et les commandes intégrées sur les commandes externes (puis $PATHdécident laquelle utiliser).

Vous pouvez forcer l'intégration avec:

builtin the-cmd and its args

(même s'il faut noter que ce n'est pas une commande standard).

Vous pouvez désactiver les alias en les citant (bien que la version citée puisse également être aliasée dans certains shells).

Ainsi, par exemple (ici la syntaxe zsh), dans:

'while'() echo function while
alias 'while=echo alias while'

L'écriture while trueproduirait en fait alias while true, et il n'y aurait aucun moyen d'utiliser le whilemot - clé car le citer désactiverait à la fois l'alias et le mot-clé.

Vous appelleriez la whilefonction avec par exemple:

'whi'le whatever

S'il y avait une fonction whileintégrée (mais bien sûr, elle ne le serait pas dans les shells qui ont un whilemot - clé), vous l'écririez:

builtin while whatever

Et pour appeler la whilecommande, vous écririez:

env while whatever

ou dans zsh(lorsqu'il n'est pas en shémulation):

command while whatever 

(dans d'autres shells, commandempêche uniquement les fonctions, pas les fonctions intégrées)

Ou

/full/path/to/while whatever

Bien sûr, rien ne vous empêche de faire des choses encore plus stupides comme:

alias 'while=while "w"hile; do'
"while"() { while "whi"le; done; }

Ce qui, au moins en zsh est valide (mais stupide).

Stéphane Chazelas
la source
La citation supprime la recherche d'alias et command supprime la recherche de fonction, mais aucune de celles-ci ne spécifie lequel des synonymes restants sera utilisé. Je cherche un moyen de spécifier d'exécuter uniquement un synonyme spécifique .
l0b0
@ l0b0 "command" supprime tous les alias, mots-clés et intégrés.
Stéphane Chazelas
Quant au sens, il builtinest utilisé par exemple dans RVM pour passer outre cdpour un bel effet.
l0b0
Tu as raison; et je viens de vérifier qu'il supprime également les fonctions. +1.
l0b0
0

Un idiome extrêmement utile pour moi est le suivant:

FALSE=1; TRUE=0
DEVEL_FLAG=$FALSE
...
in_development() { return $DEVEL_FLAG ; }
cd()
{
 if in_development ; then # -D argument to script toggles development flag
   echo "Would run cd $*"
  else
   builtin cd "$@"
 fi
}

Maintenant, si j'exécute le script avec -D spécifié, le mode de développement est activé et le cd (ou toute autre commande encapsulée) fait écho aux informations de débogage

Ceci est particulièrement utile avec les scripts qui exécutent ssh. Bien sûr, je pourrais basculer set -x, mais c'est plus utile et plus lisible pour moi.

Graham Nicholls
la source
1
Comment cela répond-il à la question?
l0b0