Tout en discutant des différences entre /usr/bin/time
le shell (bash et zsh) intégré time
, quelqu'un a mentionné que l'on peut utiliser \time
comme 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\ime
marche aussi? - Pourquoi
\cd
le répertoire change- t-il , alors que/usr/bin/cd
¹ ne change pas?
Alors évidemment, \foo
n'est pas équivalent à $(which foo)
. La question est maintenant:
Le comportement observé de \foo
bash 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/cd
est, sur mon système,
#!/bin/sh
builtin cd "$@"
shell
quoting
posix
time-utility
Jonas Schäfer
la source
la source
Réponses:
t\ime
ou\cd
(ou ou"tim"e
ou'cd'
ou${-##*}time
ou${-+time}
et toutes les autres combinaisons de citations et d'extensions auxquelles vous pourriez penser qui finiraient par se résoudre entime
oucd
), c'est que: une autre façon d'écrirecd
ettime
.Cependant, cela finirait par résoudre
cd
outime
ulté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\me
letime
mot clé shell. Donc:serait reconnu par le shell comme une simple commande par opposition au
time
mot - clé suivi d'une simple commande.Ensuite, le guillemet
ti\me
serait traité (ici, cette barre oblique inverse cite lem
caractère qui n'a pas besoin d'être cité de toute façon, le caractère guillemet est supprimé, vous obteneztime
) et unetime
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/time
ici)Car
cd
, il n'y a pas decd
mot-clé dans le langage shell, juste unecd
commande intégrée (qui a priorité sur la vôtre/usr/bin/cd
). Cependant, si vous définissez un alias pourcd
(commealias 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 pourcd
et pas un pour\cd
(notez que peu de shells autorisent les alias avec des barres obliques inverses), puis en écrivant:vous vous assurez que votre
cd
alias 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
,{
...time
est 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 faisantcommand time cmd...
) et les commandes intégrées (que vous pouvez contourner en faisantenv time cmd...
, bien que je ne sache pas un shell qui a unetime
commande 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.la source
time
etcd
qui conduit à la différence de comportement observé est qu'iltime
s'agit d'un mot clé et d'cd
une commande intégrée ?time
c'est un mot-clé et çacd
ne l'est pas. (et si vous aviez un alias pourcd
ortime
, ce serait une autre affaire). Celacd
est 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 deexport
/typeset
/declare
. Je devrais probablement ajouter une note à ce sujet dans cette réponse.