Dans le manuel de référence de Bash,
L'utilisation de
time
en tant que mot réservé permet le minutage des intégrés du shell , fonctions shell , et canalisations . Unetime
externe 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
time
externe travailler sur un shell intégré et un
pipeline, alors que la citation dit qu'il "ne peut pas les chronométrer facilement" ?time
externe 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 0swaps
time
externe 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
time
externe 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
.