Je veux exécuter quelque chose dans un shell Linux sous différentes conditions et être capable de générer le temps d’exécution de chaque exécution.
Je sais que je pourrais écrire un script perl ou python qui le ferait, mais y a-t-il un moyen de le faire dans le shell? (qui se trouve être bash)
Utilisez le mot time
clé de time
intégré:
$ temps d'aide time: time [-p] PIPELINE Exécutez PIPELINE et imprimez un résumé du temps réel en temps réel, et le temps CPU du système passé à exécuter PIPELINE quand il se termine. Le statut de retour est le statut de retour de PIPELINE. L'option `-p ' imprime le résumé de synchronisation dans un format légèrement différent. Cela utilise la valeur de la variable TIMEFORMAT comme format de sortie.
Exemple:
$ time sleep 2
vrai 0m2.009s utilisateur 0m0.000s sys 0m0.004s
Vous pouvez obtenir des informations beaucoup plus détaillées que le temps intégré bash (mentionné par Robert Gamble) en utilisant le temps (1) . Normalement, il s’agit de /usr/bin/time
.
Remarque de l’éditeur: pour vous assurer que vous appelez l’ time
utilitaire externe plutôt que le mot clé time
de votre shell, appelez-le sous la forme /usr/bin/time
.
time
est un utilitaire POSIX , mais la seule option requirejse pour la prise en charge est -p
.
Des plates-formes spécifiques implémentent des extensions non standard spécifiques: -v
fonctionne avec l’utilitaire de time
GNU , comme démontré ci-dessous (la question est balisée linux ); l’implémentation BSD / macOS utilise -l
pour produire une sortie similaire – voir man 1 time
.
Exemple de sortie verbeuse:
$ /usr/bin/time -v sleep 1 Command being timed: "sleep 1" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 1% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 0 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 210 Voluntary context switches: 2 Involuntary context switches: 1 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0
$ /usr/bin/time -v sleep 1 Command being timed: "sleep 1" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 1% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 0 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 210 Voluntary context switches: 2 Involuntary context switches: 1 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0
#!/bin/bash START=$(date +%s) # do something # start your script work here ls -R /etc > /tmp/x rm -f /tmp/x # your logic ends here END=$(date +%s) DIFF=$(( $END - $START )) echo "It took $DIFF seconds"
Pour une mesure delta ligne par ligne, essayez gnomon .
Un utilitaire de ligne de commande, un peu comme les moreutils, pour append les informations d’horodatage à la sortie standard d’une autre commande. Utile pour les processus de longue durée où vous souhaitez un historique de ce qui prend tant de temps.
Vous pouvez également utiliser les --high
et / ou --medium
pour spécifier un seuil de longueur en secondes, sur lequel gnomon mettra en évidence l’horodatage en rouge ou en jaune. Et vous pouvez faire quelques autres choses aussi.
Si vous voulez plus de précision, utilisez %N
avec date
(et utilisez bc
pour le diff, car $(())
ne gère que les entiers).
Voici comment faire:
start=$(date +%s.%N) # do some stuff here dur=$(echo "$(date +%s.%N) - $start" | bc) printf "Execution time: %.6f seconds" $dur
Exemple:
start=$(date +%s.%N); \ sleep 0.1s; \ dur=$(echo "$(date +%s.%N) - $start" | bc); \ printf "Execution time: %.6f seconds\n" $dur
Résultat:
Execution time: 0.104623 seconds
Si vous avez l’intention d’utiliser les temps plus tard pour calculer, apprenez à utiliser l’option -f
de /usr/bin/time
pour générer du code qui permet de gagner du temps. Voici un code que j’ai utilisé récemment pour obtenir et sortinger les temps d’exécution d’une classe entière de programmes pour étudiants:
fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }" /usr/bin/time -f "$fmt" -o $timefile command args...
J’ai ensuite concaténé tous les fichiers $timefile
et $timefile
la sortie dans un interpréteur Lua . Vous pouvez faire la même chose avec Python ou bash ou quelle que soit votre syntaxe préférée. J’aime cette technique.
Si vous avez seulement besoin de précision à la seconde, vous pouvez utiliser la variable intégrée $SECONDS
, qui compte le nombre de secondes pendant lesquelles le shell a été exécuté.
while true; do start=$SECONDS some_long_running_command duration=$(( SECONDS - start )) echo "This run took $duration seconds" if some_condition; then break; fi done
Vous pouvez utiliser le time
et le sous – shell ()
:
time ( for (( i=1; i<10000; i++ )); do echo 1 >/dev/null done )
Ou dans le même shell {}
:
time { for (( i=1; i<10000; i++ )); do echo 1 >/dev/null done }
Le chemin est
$ > g++ -lpthread perform.c -o per $ > time ./per
la sortie est >>
real 0m0.014s user 0m0.010s sys 0m0.002s