it-swarm-eu.dev

Jak efektivně využít čas spuštění skriptu?

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.?

392
mtk

Při volání skriptu použijte time:

time yourscript.sh
506
Trudbert

Pokud time není možnost,

start=`date +%s`
stuff
end=`date +%s`

runtime=$((end-start))
204
Rob Bos

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.

77
Stéphane Chazelas

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é!

32
jwchew

Moje metoda pro bash:

# Reset BASH time counter
SECONDS=0
    # 
    # do stuff
    # 
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
23
Mark

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% )
8
Zaahid
#!/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í.

6
Alex

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
5
Evgeny

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é.

5
LeZuse

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
3
gauteh

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)")
3
mpontillo
#!/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..."
3
Shicheng Guo

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
2
codeforester
#!/bin/bash
begin=$(date +"%s")

Script

termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
1
Arun Binoy

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

Příbuzný:

0
Gabriel Staples