Je veux exécuter quelque chose dans un shell linux sous différentes conditions et pouvoir afficher le temps d'exécution de chaque exécution.
Je sais que je pourrais écrire un script Perl ou Python pour le faire, mais y a-t-il un moyen de le faire dans le shell? (qui se trouve être bash)
Utilisez le mot clé time
intégré:
$ temps d'aide temps: temps [-p] PIPELINE Exécutez PIPELINE et imprimez un résumé du temps réel, du temps de calcul de l'utilisateur, et temps système CPU 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 la synchronisation dans un format légèrement différent. Ceci utilise la valeur de la variable TIMEFORMAT en tant que format de sortie .
Exemple:
$ time sleep 2
réel 0m2.009s utilisateur 0m0.000s sys 0m0.004s
Vous pouvez obtenir des informations beaucoup plus détaillées que la variable time
intégrée à bash (mentionnée par Robert Gamble) en utilisant time (1) . Normalement, c'est /usr/bin/time
.
Note de l'éditeur: Pour vous assurer que vous appelez l'utilitaire externaltime
plutôt que time
mot clé de votre shell, appelez-le en tant que /usr/bin/time
.time
est un utilitaire mandaté par POSIX , mais la seule option qu’il doit prendre en charge est -p
.
Des plates-formes spécifiques implémentent des extensions non standard spécifiques: -v
fonctionne avec l'utilitaire time
de GNU, comme indiqué 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
#!/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 ts de moreutils, pour ajouter des informations d’horodatage à la sortie standard d’une autre commande. Utile pour les processus de longue durée pour lesquels vous souhaitez un enregistrement historique de ce qui prend si longtemps.
Vous pouvez également utiliser les options --high
et/ou --medium
pour spécifier un seuil de longueur en secondes sur lequel gnomon mettra en surbrillance l'horodatage en rouge ou 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 le 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 heures plus tard pour calculer, découvrez comment utiliser l'option -f
de /usr/bin/time
pour sortir code qui enregistre les temps. Voici un code que j'ai utilisé récemment pour obtenir et trier les temps d'exécution d'un grand nombre de programmes d'é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 ai transféré 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'adore cette technique.
Si vous avez seulement besoin de précision à la seconde près, vous pouvez utiliser la variable intégrée $SECONDS
, qui compte le nombre de secondes d’exécution du shell.
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 time
et subshell ()
:
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
une méthode éventuellement simple (qui peut ne pas répondre aux besoins des différents utilisateurs) est l’utilisation de Shell Prompt.it est une solution simple qui peut être utile dans certains cas. Vous pouvez utiliser la fonctionnalité d'invite bash comme dans l'exemple ci-dessous:
export PS1 = '[\ t\u @\h]\$'
La commande ci-dessus entraînera la modification de l'invite du shell en:
[HH: MM: Nom d'utilisateur SS @ nom d'hôte] $
Chaque fois que vous exécutez une commande (ou appuyez sur Entrée) pour revenir à l'invite du shell, l'invite affiche l'heure actuelle.
Remarques:
1) Attention, si vous attendez quelque temps avant de taper votre commande suivante, vous devez tenir compte de cette heure, c’est-à-dire que l’heure affichée dans l’invite du shell est l’horodatage de l’invite du shell, et non quand vous entrez la commande. Certains utilisateurs choisissent d'appuyer sur la touche Entrée pour obtenir une nouvelle invite avec un nouvel horodatage avant d'être prêts pour la commande suivante.
2) Il existe d’autres options et modificateurs pouvant être utilisés pour modifier l’invite bash, reportez-vous à (man bash) pour plus de détails.