Juste une petite question sur le timing des programmes sous Linux: la commande time permet de mesurer le temps d'exécution d'un programme:
[ed@lbox200 ~]$ time sleep 1
real 0m1.004s
user 0m0.000s
sys 0m0.004s
Ce qui fonctionne bien. Mais si j'essaie de rediriger la sortie vers un fichier, cela échoue.
[ed@lbox200 ~]$ time sleep 1 > time.txt
real 0m1.004s
user 0m0.001s
sys 0m0.004s
[ed@lbox200 ~]$ cat time.txt
[ed@lbox200 ~]$
Je sais qu'il existe d'autres implémentations de temps avec l'option -o pour écrire un fichier, maismy question concerne la commande sans ces options.
Aucune suggestion ?
Essayer
{ time sleep 1 ; } 2> time.txt
qui combine le STDERR de "time" et votre commande en time.txt
Ou utiliser
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
qui met STDERR de "sleep" dans le fichier "sleep.stderr" et que seul STDERR de "time" entre dans "time.txt"
Enroulez time
et la commande que vous chronométrez dans un ensemble de crochets.
Par exemple, les temps suivants ls
et écrit le résultat de ls
et les résultats du minutage dans outfile
:
$ (time ls) > outfile 2>&1
Ou, si vous souhaitez séparer la sortie de la commande de la sortie capturée de time
:
$ (time ls) > ls_results 2> time_results
Simple. L'utilitaire GNU time
a une option pour cela.
Mais vous devez vous assurer que vous utilisez non en utilisant la commande time
intégrée de votre shell, au moins la commande intégrée bash
ne fournit pas cette option! C'est pourquoi vous devez indiquer le chemin complet de l'utilitaire time
:
/usr/bin/time -o time.txt sleep 1
Si vous vous souciez de la sortie d'erreur de la commande, vous pouvez les séparer ainsi tout en continuant d'utiliser la commande time intégrée.
{ time your_command 2> command.err ; } 2> time.log
ou
{ time your_command 2>1 ; } 2> time.log
Lorsque vous voyez les erreurs de la commande, accédez à un fichier (puisque stderr
est utilisé pour time
).
Malheureusement, vous ne pouvez pas l'envoyer à un autre identifiant (comme 3>&2
) car il n'existera plus en dehors du {...}
Cela dit, si vous pouvez utiliser le temps GNU, faites ce que @ Tim Ludwinski a dit.
\time -o time.log command
Puisque la sortie de la commande 'time' est une sortie d'erreur, la rediriger comme une sortie standard serait plus intuitive pour effectuer un traitement ultérieur.
{ time sleep 1; } 2>&1 | cat > time.txt
Si vous utilisez le temps GNU au lieu de la bash intégrée, essayez
time -o outfile command
(Remarque: le format de l'heure GNU est un peu différent de celui de bash intégré)
&>out time command >/dev/null
dans ton cas
&>out time sleep 1 >/dev/null
puis
cat out
J'ai fini par utiliser:
/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
#!/bin/bash
set -e
_onexit() {
[[ $TMPD ]] && rm -rf "$TMPD"
}
TMPD="$(mktemp -d)"
trap _onexit EXIT
_time_2() {
"$@" 2>&3
}
_time_1() {
time _time_2 "$@"
}
_time() {
declare time_label="$1"
shift
exec 3>&2
_time_1 "$@" 2>"$TMPD/timing.$time_label"
echo "time[$time_label]"
cat "$TMPD/timing.$time_label"
}
_time a _do_something
_time b _do_another_thing
_time c _finish_up
Cela a l'avantage de ne pas générer de sous-coquilles, et le dernier pipeline a son stderr restauré dans le réel.
Si vous utilisez csh
, vous pouvez utiliser:
/usr/bin/time --output=outfile -p $Shell -c 'your command'
Par exemple:
/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
Si vous ne souhaitez pas toucher aux commandes stdout et stderr du processus d'origine, vous pouvez rediriger stderr vers le descripteur de fichier 3 et inversement:
$ { time { Perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out
real 0m0.009s
user 0m0.004s
sys 0m0.000s
Vous pouvez l'utiliser pour un wrapper (par exemple, pour les tâches cron) afin de surveiller les temps d'exécution:
#!/bin/bash
echo "[$(date)]" "$@" >> /my/runtime.log
{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log