Chtěl bych zobrazit čas dokončení skriptu.
V současné době dělám -
#!/bin/bash
date ## echo the date at start
# the script contents
date ## echo the date at end
Toto jen ukazuje čas začátku a konce skriptu. Bylo by možné zobrazit jemnozrnný výstup, jako je čas procesoru/čas io atd.?
Při volání skriptu použijte time
:
time yourscript.sh
Pokud time
není možnost,
start=`date +%s`
stuff
end=`date +%s`
runtime=$((end-start))
Po opuštění skriptu stačí zavolat times
bez argumentů.
Pomocí ksh
nebo zsh
můžete místo toho použít time
. Pomocí zsh
vám time
dá kromě času a systémový čas CPU.
Chcete-li zachovat stav ukončení skriptu, můžete jej provést:
ret=$?; times; exit "$ret"
Nebo můžete také přidat past do EXIT
:
trap times EXIT
Tímto způsobem budou časy vyvolávány vždy, když Shell opustí a stav ukončení bude zachován.
$ bash -c 'trap times EXIT; : {1..1000000}'
0m0.932s 0m0.028s
0m0.000s 0m0.000s
$ zsh -c 'trap time EXIT; : {1..1000000}'
Shell 0.67s user 0.01s system 100% cpu 0.677 total
children 0.00s user 0.00s system 0% cpu 0.677 total
Všimněte si také, že všechny bash
, ksh
a zsh
mají $SECONDS
speciální proměnná, která se každou sekundu automaticky zvyšuje. zsh
a ksh93
, tato proměnná může být také plovoucí desetinnou čárkou (s typeset -F SECONDS
) pro získání větší přesnosti. Toto je pouze čas nástěnných hodin, nikoli čas CPU.
Trochu pozdě do rozjetého vlaku, ale chtěl jsem zveřejnit své řešení (pro přesnost vteřiny) pro případ, že by ostatní náhodou narazili na toto vlákno při hledání. Výstup je ve formátu dní, hodin, minut a nakonec sekund:
res1=$(date +%s.%N)
# do stuff in here
res2=$(date +%s.%N)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)
LC_NUMERIC=C printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds
Doufám, že někdo tam najde to užitečné!
Moje metoda pro bash
:
# Reset BASH time counter
SECONDS=0
#
# do stuff
#
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
Tato otázka je dost stará, ale ve snaze najít můj oblíbený způsob, jak to udělat, toto vlákno vyšlo vysoko ... a jsem překvapen, že to nikdo nezmínil:
perf stat -r 10 -B sleep 1
'perf' je nástroj pro analýzu výkonu, který je součástí jádra v části 'tools/perf' a je často k dispozici pro instalaci jako samostatný balíček ('perf' v CentOS a 'linux-tools' na Debian/Ubuntu). Linux Kernal perf Wiki má mnohem více informací.
Spuštění funkce „perf stat“ poskytuje docela dost podrobností včetně průměrné doby provedení přímo na konci:
1.002248382 seconds time elapsed ( +- 0.01% )
#!/bin/bash
start=$(date +%s.%N)
# HERE BE CODE
end=$(date +%s.%N)
runtime=$(python -c "print(${end} - ${start})")
echo "Runtime was $runtime"
Ano, to volá Python, ale pokud s tím dokážete žít, pak je to docela pěkné, napjaté řešení.
Malá funkce Shell, kterou lze přidat před příkazy k měření jejich času:
tm() {
local start=$(date +%s)
[email protected]
local exit_code=$?
echo >&2 "took ~$(($(date +%s)-${start})) seconds. exited with ${exit_code}"
return $exit_code
}
Pak to použijte ve skriptu nebo na příkazovém řádku takto:
tm the_original_command with all its parameters
Osobně rád zabalím veškerý skriptový kód do nějaké „hlavní“ funkce, jako je tato:
main () {
echo running ...
}
# stuff ...
# calling the function at the very end of the script
time main
Všimněte si, jak snadné je v tomto scénáři použít příkaz time
. Je zřejmé, že neměříte přesný čas, včetně analýzy času skriptu, ale ve většině situací to považuji za dostatečně přesné.
Pomocí pouze bash je také možné změřit a vypočítat dobu trvání pro část skriptu Shell (nebo uplynulý čas pro celý skript):
start=$SECONDS
... # do time consuming stuff
end=$SECONDS
nyní můžete buď jen vytisknout rozdíl:
echo "duration: $((end-start)) seconds."
pokud potřebujete pouze přírůstkové trvání, proveďte:
echo "duration: $((SECONDS-start)) seconds elapsed.."
Trvání můžete také uložit do proměnné:
let diff=end-start
Zde je variace Alexovy odpovědi. Zajímalo mě jen minuty a sekundy, ale také jsem chtěl, aby byl formátován odlišně. Tak jsem to udělal:
start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")
#!/bin/csh
#PBS -q glean
#PBS -l nodes=1:ppn=1
#PBS -l walltime=10:00:00
#PBS -o a.log
#PBS -e a.err
#PBS -V
#PBS -M [email protected]
#PBS -m abe
#PBS -A k4zhang-group
START=$(date +%s)
for i in {1..1000000}
do
echo 1
done
END=$(date +%s)
DIFF=$(echo "$END - $START" | bc)
echo "It takes DIFF=$DIFF seconds to complete this task..."
Funkce časování založená na SECONDS
, omezená pouze na granularitu druhé úrovně, nepoužívá žádné externí příkazy:
time_it() {
local start=$SECONDS ts ec
printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
printf '%s\n' "$ts Starting $*"
"[email protected]"; ec=$?
printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
printf '%s\n' "$ts Finished $*; elapsed = $((SECONDS-start)) seconds"
# make sure to return the exit code of the command so that the caller can use it
return "$ec"
}
Například:
time_it sleep 5
dává
2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished
sleep 5; elapsed = 5 seconds
#!/bin/bash
begin=$(date +"%s")
Script
termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
Pro bash použijte interní $SECONDS
proměnná. Zde je ukázka:
Všimněte si, že dt_min
se zaokrouhlí od 0.01666666666...
(1 sekunda = tolik minut) do 0.017
v tomto případě, protože používám funkci printf
k zaokrouhlení. The sleep 1;
část níže je místo, kde byste chtěli spustit skript a čas, ale kvůli této ukázce jen spím na 1 sekundu:
start=$SECONDS; sleep 1; end=$SECONDS; dt_sec=$(( end - start )); dt_min=$(printf %.3f $(echo "$dt_sec/60" | bc -l)); echo "dt_sec = $dt_sec; dt_min = $dt_min"
dt_sec = 1; dt_min = 0.017
bc
a printf
ve své odpovědi zde: https://stackoverflow.com/questions/12722095/how-do-i-use-floating-point-division -in-bash/58479867 # 58479867