Que font réellement «\ time», «t \ ime» et «\ cd»? (amusant avec des barres obliques inversées dans les coquilles)

9

Tout en discutant des différences entre /usr/bin/timele shell (bash et zsh) intégré time, quelqu'un a mentionné que l'on peut utiliser \timecomme raccourci pour obtenir /usr/bin/time.

Au début, cela semblait être un bon raccourci innocent, mais ensuite quelques questions se sont posées:

  • Pourquoi ça t\imemarche aussi?
  • Pourquoi \cdle répertoire change- t-il , alors que /usr/bin/cd¹ ne change pas?

Alors évidemment, \foon'est pas équivalent à $(which foo). La question est maintenant:

Le comportement observé de \foobash et zsh est-il couvert de quelque manière que ce soit par la définition POSIX d'un shell, et si oui, pourquoi se comporte-t-il comme il le fait?


Note de bas de page 1: /usr/bin/cdest, sur mon système,

#!/bin/sh
builtin cd "$@"
Jonas Schäfer
la source
Voir aussi unix.stackexchange.com/questions/12762/… Notez que \ command est une fonctionnalité tcsh spécifiquement documentée qui dit d'ignorer les alias de la commande.
simpleuser

Réponses:

14

t\imeou \cd(ou ou "tim"eou 'cd'ou ${-##*}timeou ${-+time}et toutes les autres combinaisons de citations et d'extensions auxquelles vous pourriez penser qui finiraient par se résoudre en timeou cd), c'est que: une autre façon d'écrire cdet time.

Cependant, cela finirait par résoudre cdou timeultérieurement l'analyse syntaxique et l'interprétation de la syntaxe du shell. En particulier, cela se produit longtemps après la reconnaissance des mots clés du shell et la substitution d' alias .

Ainsi, au moment où le shell recherche des mots clés dans sa langue, il ne reconnaît pas ti\mele timemot clé shell. Donc:

ti\me echo test

serait reconnu par le shell comme une simple commande par opposition au timemot - clé suivi d'une simple commande.

Ensuite, le guillemet ti\meserait traité (ici, cette barre oblique inverse cite le mcaractère qui n'a pas besoin d'être cité de toute façon, le caractère guillemet est supprimé, vous obtenez time) et une time commande serait consultée comme toutes les autres commandes (dans la liste des commandes intégrées) , les fonctions et les fichiers exécutables $PATH. Très probablement qui seront /bin/timeici)

Car cd, il n'y a pas de cdmot-clé dans le langage shell, juste une cdcommande intégrée (qui a priorité sur la vôtre /usr/bin/cd). Cependant, si vous définissez un alias pour cd(comme alias cd=pushd), même chose. Comme la substitution d'alias est effectuée très tôt, avant la suppression des guillemets, si vous avez un alias pour cdet pas un pour \cd(notez que peu de shells autorisent les alias avec des barres obliques inverses), puis en écrivant:

\cd dir

vous vous assurez que votre cdalias n'est pas remplacé.

En bref, citant un nom de commande ou une partie de celui - ci l'empêche d'être considéré comme un mot - clé shell (mots - clés étant des choses comme while, for, if, {... timeest un mot - clé dans quelques coquilles seulement), et contournements un alias que vous pouvez avoir pour elle .

Cependant, il ne force pas cette commande à se résoudre en un fichier exécutable $PATH, la commande est toujours recherchée en premier parmi les fonctions (que vous pouvez contourner en faisant command time cmd...) et les commandes intégrées (que vous pouvez contourner en faisant env time cmd..., bien que je ne sache pas un shell qui a une timecommande intégrée ).

Notez que la citation peut également avoir une influence sur le comportement des commandes spéciales de la famille typeset/ declare/ export/ local... dans certains shells. Voir Des devis sont - ils nécessaires pour l'affectation de variable locale? pour plus de détails.

Stéphane Chazelas
la source
Ainsi, la différence entre timeet cdqui conduit à la différence de comportement observé est qu'il times'agit d'un mot clé et d' cdune commande intégrée ?
Jonas Schäfer
1
@JonasWielicki, c'est que timec'est un mot-clé et ça cdne l'est pas. (et si vous aviez un alias pour cdor time, ce serait une autre affaire). Cela cdest intégré ou non n'a aucune incidence à ce stade (en ce qui concerne l'influence de la citation). Certains shells ont cependant quelques buildins qui sont à mi-chemin entre les mots-clés et les builtins car leur analyse est effectuée différemment des autres buildins. C'est le cas de export/ typeset/ declare. Je devrais probablement ajouter une note à ce sujet dans cette réponse.
Stéphane Chazelas