Dans le manuel de référence de Bash,
L'utilisation de
timeen tant que mot réservé permet le minutage des intégrés du shell , fonctions shell , et canalisations . Unetimeexterne la commande ne peut pas les chronométrer facilement.
-
Pourriez-vous expliquer pourquoi la citation dit cela ?
Est-ce à cause de la différence entre un mot réservé et une
commande, pas seulement limitée au cas detime? Par exemple, comment le shell bash
les analyse-t-il ou les interprète-t-il différemment ?Ou est-ce seulement limité au cas de
time? -
Dans les exemples suivants,
pourquoi le
timeexterne travailler sur un shell intégré et un
pipeline, alors que la citation dit qu'il "ne peut pas les chronométrer facilement" ?timeexterne sur un shell intégré :$ /usr/bin/time echo hello hello 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 1676maxresident)k 0inputs+0outputs (0major+78minor)pagefaults 0swapstimeexterne sur un pipeline :$ /usr/bin/time sleep 10 | sleep 5 0.00user 0.00system 0:10.00elapsed 0%CPU (0avgtext+0avgdata 1776maxresident)k 0inputs+0outputs (0major+79minor)pagefaults 0swaps -
Dans l'exemple suivant, pourquoi le
timeexterne sur une fonction
shell échouer? Que signifie sa sortie d'erreur ?$ function mytest () { sleep 10; } $ /usr/bin/time mytest /usr/bin/time: cannot run mytest: No such file or directory Command exited with non-zero status 127 0.00user 0.00system 0:00.03elapsed 0%CPU (0avgtext+0avgdata 1252maxresident)k 32inputs+0outputs (0major+30minor)pagefaults 0swaps -
Il semble que la citation ne s'applique pas seulement aux commandes intégrées du shell de synchronisation,
aux fonctions du shell et aux pipelines, mais également à la synchronisation d'un groupe de
commandes :$ time { echo hello; sleep 3; echo tim; } hello tim real 0m3.002s user 0m0.000s sys 0m0.000s $ /usr/bin/time { echo hello; sleep 3; echo tim; } bash: syntax error near unexpected token `}'Pourquoi le shell dit-il "bash :erreur de syntaxe près d'un jeton inattendu
}” dans le cas de la commande/usr/bin/time?
Réponse acceptée :
Dans bash , time est un mot réservé, de sorte que le shell peut l'analyser à sa manière et lui appliquer des règles.
Voici le code montrant comment bash la ligne d'analyse commence par time mot réservé :
static int
time_command_acceptable ()
{
#if defined (COMMAND_TIMING)
int i;
if (posixly_correct && shell_compatibility_level > 41)
{
/* Quick check of the rest of the line to find the next token. If it
begins with a `-', Posix says to not return `time' as the token.
This was interp 267. */
i = shell_input_line_index;
while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == 't'))
i++;
if (shell_input_line[i] == '-')
return 0;
}
switch (last_read_token)
{
case 0:
case ';':
case 'n':
case AND_AND:
case OR_OR:
case '&':
case WHILE:
case DO:
case UNTIL:
case IF:
case THEN:
case ELIF:
case ELSE:
case '{': /* } */
case '(': /* )( */
case ')': /* only valid in case statement */
case BANG: /* ! time pipeline */
case TIME: /* time time pipeline */
case TIMEOPT: /* time -p time pipeline */
case TIMEIGN: /* time -p -- ... */
return 1;
default:
return 0;
}
#else
return 0;
#endif /* COMMAND_TIMING */
}
Vous voyez, time peut être suivi par la plupart des autres bash mots réservés.
En cas de commande externe, la règle normale a été appliquée, { a été considéré comme une entrée de /usr/bin/time . } seul est un jeton invalide et bash augmenter l'erreur.
Dans :
/usr/bin/time echo hello
time externe n'a pas appelé le shell intégré echo mais l'echo externe commande.
Une strace vérifie que :
$ strace -fe execve /usr/bin/time echo 1
execve("/usr/bin/time", ["/usr/bin/time", "echo", "1"], [/* 64 vars */]) = 0
Process 25161 attached
....
[pid 25161] execve("/usr/bin/echo", ["echo", "1"], [/* 64 vars */]) = -1 ENOENT (No such file or directory)
[pid 25161] execve("/bin/echo", ["echo", "1"], [/* 64 vars */]) = 0
1
[pid 25161] +++ exited with 0 +++
....
Ici time externe recherchez votre PATH variable pour trouver l'exécutable de la commande. Cela explique également en cas d'utilisation d'une fonction, vous avez Aucun fichier ou répertoire de ce type car il n'y a pas de commande nommée mytest dans votre PATH .