Est-il un moyen de trouver le temps d'exécution de la dernière commande exécutée dans le shell?

Existe-t-il une commande comme time qui peut afficher les détails de la durée d'exécution des dernières ou des dernières commandes exécutées sur le shell?

23
demandé sur Behrang 2010-04-24 17:37:11

5 réponses

Je ne sais pas, comment c'est dans bash, mais dans zsh vous pouvez définir preexec et precmd fonctions afin qu'ils économisent le temps actuel aux variables $STARTTIME (preexec) et $ENDTIME (precmd) de sorte que vous serez en mesure de trouver le temps d'exécution approximatif. Ou vous pouvez définir une fonction accept-line afin qu'elle ajoute time avant chaque commande.

Mise à jour : C'est le code, qui stockera les temps écoulés dans le tableau $_elapsed:

preexec () {
   (( $#_elapsed > 1000 )) && set -A _elapsed $_elapsed[-1000,-1]
   typeset -ig _start=SECONDS
}
precmd() { set -A _elapsed $_elapsed $(( SECONDS-_start )) }

Alors, si vous exécutez sleep 10s:

% set -A _elapsed # Clear the times
% sleep 10s
% sleep 2s ; echo $_elapsed[-1]
10
% echo $_elapsed
0 10 0

Pas besoin d'entrer quatre variables. Aucun problème avec les noms ou les retards supplémentaires. Notez simplement que $_elapsed array peut devenir très grand, vous devez donc supprimer les premiers éléments (ceci est fait avec le morceau de code suivant: (( $#_elapsed > 1000 )) && set -A _elapsed $_elapsed[-1000,-1]).

UPDATE2 : Trouvé le script pour prendre en charge precmd de style zsh et preexec dans bash. Peut-être que vous aurez besoin de supprimer typeset -ig (j'ai utilisé juste pour forcer $_start à être entier) et remplacer set -A var ... par var=( ... ) pour que cela fonctionne. Et je ne sais pas comment découper des tableaux et obtenir leur longueur en bash.

Script: http://www.twistedmatrix.com/users/glyph/preexec.bash.txt

Mise à jour3 : Trouvé un problème: si vous appuyez sur return avec une ligne vide, preexec ne s'exécute pas, alors que precmd le fait, vous obtiendrez donc des valeurs sans signification dans le tableau $_elapsed. Pour résoudre ce problème, remplacez la fonction precmd par le code suivant:

precmd () {
   (( _start >= 0 )) && set -A _elapsed $_elapsed $(( SECONDS-_start ))
   _start=-1 
}
13
répondu ZyX 2010-04-24 20:30:33

Modifier 3:

La structure de cette réponse:

  1. Il N'y a pas de moyen prêt à l'emploi pour chronométrer une commande qui a déjà été exécutée
  2. Il existe des moyens de déduire une estimation de la durée d'exécution d'une commande.
  3. une preuve de concept est montrée (en commençant par l'hypothèse que cela ne peut pas être fait et en terminant par la conclusion que l'hypothèse était fausse).
  4. Il y a des hacks que vous pouvez mettre en place avant-main qui enregistrera le temps écoulé de chaque commande que vous exécutez
  5. Conclusion

La réponse étiquetée par ses parties selon le contour ci-dessus:

Partie 1 - la réponse est "non"

d'Origine

Non, désolé. Vous devez utiliser time.

Partie 2 - peut-être que vous pouvez en déduire un résultat

Dans certains cas, si un programme écrit des fichiers de sortie ou des informations dans des capable de déduire le temps d'exécution, mais ce serait spécifique au programme et seulement une supposition. Si vous avez HISTTIMEFORMAT défini dans Bash, vous pouvez regarder les entrées dans le fichier d'historique pour avoir une idée du moment où un programme a démarré. Mais l'Heure de fin n'est pas enregistrée, vous ne pouvez donc déduire une durée que si un autre programme a été démarré immédiatement après la fin de celui qui vous intéresse.

Partie 3 - une hypothèse est falsifié

hypothèse : Le temps D'inactivité sera compté dans le temps écoulé

Modifier:

Voici un exemple pour illustrer mon point. Il est basé sur la suggestion de ZyX, mais serait similaire en utilisant d'autres méthodes.

Dans zsh:

% precmd() { prevstart=start; start=$SECONDS; }
% preexec() { prevend=$end; end=$SECONDS; }
% echo "T: $SECONDS ps: $prevstart pe: $prevend s: $start e: $end"
T: 1491 ps: 1456 pe: 1458 s: 1459 e: 1491

Maintenant, nous attendons... disons pendant 15 secondes, alors:

% echo "T: $SECONDS"; sleep 10
T: 1506

Maintenant, nous attendons... disons pour 20 secondes, alors:

% echo "T: $SECONDS ps: $prevstart pe: $prevend s: $start e: $end"
T: 1536 ps: 1492 pe: 1506 s: 1516 e: 1536

Comme vous pouvez le voir, j'ai été mal. L'Heure de début (1516) moins l'Heure de fin précédente (1506) est la durée de la commande (sleep 10). ce qui montre également que les variables que j'ai utilisées dans les fonctions ont besoin de meilleurs noms.

Hypothèse falsifiés - il est possible d'obtenir le bon temps écoulé sans y compris le temps d'inactivité

Partie 4 - un hack pour enregistrer le temps écoulé de tous les commande

Modifier 2:

Voici les équivalents Bash du fonctions dans la réponsede ZyX (elles nécessitent le script lié à celui-ci):

preexec () {
   (( ${#_elapsed[@]} > 1000 )) && _elapsed=(${_elapsed[@]: -1000})
   _start=$SECONDS
}

precmd () {
   (( _start >= 0 )) && _elapsed+=($(( SECONDS-_start )))
   _start=-1 
}

Après avoir installé preexec.bash (à partir du script lié) et créé les deux fonctions ci-dessus, l'exemple d'exécution ressemblerait à ceci:

$ _elapsed=() # Clear the times
$ sleep 10s
$ sleep 2s ; echo ${_elapsed[@]: -1}
10
$ echo ${_elapsed[@]}
0 10 2

Partie 5 - conclusion

Utilisez time.

5
répondu Dennis Williamson 2010-04-25 02:40:48

Je suppose que vous exécutez des commandes qui prennent beaucoup de temps et ne réalisent pas au début que vous souhaitez chronométrer combien de temps elles prennent pour terminer. Dans zsh, si vous définissez la variable D'environnement REPORTTIME sur un nombre, toute commande prenant plus de temps que ce nombre de secondes aura le temps qu'il a fallu imprimé comme si vous l'aviez exécuté avec la commande time en face de lui. Vous pouvez le mettre dans votre .zshrc afin que les commandes longues aient toujours leur temps imprimé. Notez que le temps passé le sommeil (par opposition à l'heure utilisateur / système) n'est pas compté pour déclencher la minuterie mais est toujours suivi.

4
répondu Joseph Garvin 2012-07-02 22:13:23

Le monde a peut-être évolué un peu depuis que d'autres personnes ont répondu à ces questions.

zsh a quelques fonctionnalités intégrées pour chronométrer combien de temps les commandes prennent.

Si vous activez l'option inc_append_history_time avec

setopt inc_append_history_time

Ensuite, le temps nécessaire pour exécuter chaque commande est enregistré dans votre historique et peut ensuite être consulté avec history -D.

3
répondu Att Righ 2016-02-21 01:09:05

Je pense que vous ne pouvez obtenir que des statistiques de synchronisation pour les commandes que vous exécutez en utilisant la commande 'time'.

Depuis la page de manuel:

Temps [options] commande [arguments...]

DESCRIPTION La commande time exécute la commande program spécifiée avec les arguments donnés. Lorsque la commande se termine, time écrit un message à l'erreur standard donnant des statistiques de synchronisation sur cette exécution du programme.

1
répondu pau.estalella 2010-04-24 13:45:06