Szeretném megjeleníteni egy szkript befejezési idejét.
Amit jelenleg csinálok, az –
#!/bin/bash date ## echo the date at start # the script contents date ## echo the date at end
Ez csak a szkript kezdetének és végének idejét mutatja. finom szemcsés kimenet jeleníthető meg, például a processzor ideje / io idő stb.?
Megjegyzések
- stackoverflow.com/questions/385408/ …
- Úgy gondolom, hogy a jelenlegi elfogadott válasz nem igazán elegendő az időbeli ingadozások miatt.
- @CiroSantilli 烏坎 事件 2016 六四 事件 法轮功 Úgy gondolom, hogy a javasolt szálad még mindig nem elegendő az időbeli események hatásának kiküszöbölésére.
- Szintén kapcsolódó: stackoverflow.com/questions/5152858/… vagy kissé unix.stackexchange.com/questions/334145 / …
- Van egy parancs, amelyet futtathat, majd automatikusan megszünteti az összes unix parancsot, elfelejtette engedélyezni?
Válasz
Jus A szkript meghívásakor ne használja a time
-t:
time yourscript.sh
megjegyzések
- Ez háromszor ad ki:
real
,user
éssys
. Ezek jelentését lásd: itt . - és ” real ” valószínűleg az, amit tudni akarnak az emberek – ” A valós a falióra ideje – a hívás kezdetétől a végéig tartó idő
time $( ... ) >> out.txt
time (command1 && command2)
Válasz
Ha time
nincs lehetőség,
start=`date +%s` stuff end=`date +%s` runtime=$((end-start))
Megjegyzések
- Ne feledje, hogy ez csak akkor működik, ha nem kell ‘ szüksége a másodperc alatti pontosságra. Néhány felhasználásnál ez elfogadható lehet mások számára nem. Valamivel jobb pontosság érdekében (‘ még mindig kétszer hívja meg például a
date
-t, így a a legjobb ha milliszekundumos pontosságú a gyakorlatban, és valószínűleg kevesebb is), próbálkozzon adate +%s.%N
használatával. (%N
nanoszekundum, mivel az egész másodperc .) - @ChrisH Oh. Jó rámutatni; a bash aritmetikai bővítése csak egész szám. Két obvi-t látok ous opciók; vagy árkolja el a periódust a dátumformátum-karakterláncban (és az eredő értéket korszak óta nanoszekundumként kezeli), ezért használja a
date +%s%N
elemet, vagy használjon valami alkalmasabbat, például abc
a tényleges futási idő kiszámításához a két értékből, mint például a jwchew. Ennek ellenére úgy érzem, hogy ez a megközelítés nem optimális módja ennek; Atime
lényegesen jobb, ha rendelkezésre áll, a fentiekben vázolt okokból. - Csak telepítse a
bc
alkalmazást, majd tegye ezt:runtime=$( echo "$end - $start" | bc -l )
- Ha a szkript több percet vesz igénybe, használja a következőt:
echo "Duration: $((($(date +%s)-$start)/60)) minutes
- Tovább a @ rubo77 címre megjegyzés, ha a szkripted több órát vesz igénybe, használd a
hours=$((runtime / 3600)); minutes=$(( (runtime % 3600) / 60 )); seconds=$(( (runtime % 3600) % 60 )); echo "Runtime: $hours:$minutes:$seconds (hh:mm:ss)"
Válasz
Csak a times
hívása argumentumok nélkül a szkriptből való kilépéskor.
ksh
vagy zsh
, használhatja helyette az time
-t is. A zsh
használatával a time
a faliórát is megadja a felhasználó és mellett system CPU idő.
A szkript kilépési állapotának megőrzése érdekében megteheti:
ret=$?; times; exit "$ret"
Vagy Ön csapdát is hozzáadhat a EXIT
címre:
trap times EXIT
Így a rendszer a héj kilépésekor meghívja az időket, és a kilépési állapot megmarad.
$ 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
Ne feledje, hogy a bash
, ksh
és zsh
rendelkezik egy $SECONDS
speciális változóval, amely másodpercenként automatikusan növekszik. Mind a zsh
, mind a ksh93
esetében ez a változó lebegőponttá is tehető (typeset -F SECONDS
) a nagyobb pontosság érdekében. Ez csak a falióra ideje, nem a CPU-idő.
Megjegyzések
- Ez a $ SECONDS változó nagyon hasznos, köszönöm!
- Megszünteti-e megközelítése az időbeli események hatását? – – Úgy gondolom, hogy megközelítése közel áll a korábban bemutatott
time
megközelítéshez.- – Úgy gondolom, hogy a MATLAB kódban bemutatotttimeit
megközelítés itt hasznos lehet. - Szia, @St é phane Chazelas. Úgy találtam, hogy
times
nem ad ‘ nem ad falidőt, igaz? példáulbash -c 'trap times EXIT;sleep 2'
- @Binarus, igen, ez a szolgáltatás a ksh-ből származik. A ksh93 / zsh-vel ellentétben a lebegőpontot nem támogató bash mellett ‘ abban is megszakad, hogy miután a SECONDS értéket 0-ra állította, később 0-ról 1 másodpercre 1-re változik ( mivel csak a
time()
eredményét veszi figyelembe, amelynek csak a teljes második részletessége van). - @Binarus, nem pedig azt, hogy ‘ s 0 és 1 között. Ha a SECONDS értéket 0-ra állítja 12: 00: 00.000-kor, akkor ez egy másodperccel később 1-re változik. De ha 12: 00: 00.999-re állítja, később 1 milliszekundumra változik. De igen, egyetértek azzal, hogy valószínűleg ‘ nincs jelentősége a gyakorlatban, ha egyébként nincs ‘ pontja másodperc alatt.
Válasz
Későn érkeztem a sávhoz, de el akartam küldeni a megoldásomat (a másodperc alatti pontosság érdekében) ) arra az esetre, ha mások véletlenül ráakadnának erre a szálra a keresés során. A kimenet napok, órák, percek és végül másodpercek formátumú:
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
Remélem, hogy valaki odakinn hasznosnak találja ezt!
Megjegyzések
- Azt hiszem, nincs más (csak bash) módszer, kivéve a ‘ bc ‘ a számítások elvégzéséhez. BTW nagyon jó szkript;)
- Vigyázzon, hogy a FreeBSD ‘ Az s
date
nem támogatja a másodperc alatti pontosságot, és csak a szó szerinti „N
” szót fűzi az időbélyeghez. - Nagyon szép szkript, de a bash nem ‘ t ne kezelje az alsodik részt. Azt is megtanultam, hogy a / 1 BC-ben ezt hatékonyan levetkőzi, ezért hozzáadtam a $ /s @ értéket a $ ds számításhoz, és most nagyon szép dolgokat jelenít meg.
- A bc támogatja a modulo:
dt2=$(echo "$dt%86400" | bc)
. Csak azt mondom … BTW inkább adt2=$(bc <<< "${dt}%86400")
formát preferálom, de a ‘ teljesen személyes. - Nem ‘ még nem tud semmit a
bc
-ről, de az86400
által történő felosztás bizalmatlanná tesz a következő ok: Vannak olyan napok, amelyek nem rendelkeznek 86400 másodperccel, például olyan napok, amikor az idő DST-ről normál időre változik, és fordítva, vagy szökő másodpercekkel rendelkező napok. Ha az ilyen napok a számítani kívánt időtartam részét képezik, azazres1
ésres2
között vannak (ezeket az értékeket is beleértve), akkor a parancsfájl valószínűleg nem fog sikerülni.
Válasz
Saját módszer a bash
:
# Reset BASH time counter SECONDS=0 # # do stuff # ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
Megjegyzések
- Ez az eltelt időt mutatja, de nem ‘ t ” finom szemcsés kimenetet mutat, például a processzor idejét, az I / O időt “, ahogyan azt a kérdés megkívánja.
- Akik a feltett kérdésre választ keresnek, valószínűleg hasznosnak találják ezt a megoldást. Megjegyzésed jobban szólna az OP-k kérdéséről.
Válasz
Személy szerint szeretném az összes szkriptkód néhány “main” funkcióban, például:
main () { echo running ... } # stuff ... # calling the function at the very end of the script time main
Figyelje meg, mennyire egyszerű használni a time
parancsot ebben a forgatókönyvben. Nyilvánvaló, hogy nem a pontos időt méri, beleértve a parancsfájl elemzési idejét is, de a legtöbb helyzetben elég pontosnak találom.
Megjegyzések
- Remek megoldás, nem igényel további eszközöket, és önálló.
Válasz
#!/bin/bash start=$(date +%s.%N) # HERE BE CODE end=$(date +%s.%N) runtime=$(python -c "print(${end} - ${start})") echo "Runtime was $runtime"
Igen, ez meghívja a Python-ot, de ha tudsz ezzel élni, akkor ez nagyon szép, szűkszavú megoldás.
Megjegyzések
- Vigyázzon, hogy a
python
parancs futtatása egy alhéjban és annak kimenetének kiolvasása több millió nanoszekundumot vesz igénybe a legtöbb jelenlegi rendszeren. div id = “33e4a5674d”>
.
$(echo $end - $start | bc)
ugyanazt fogja tenni python nélkül Válasz
Ez a kérdés meglehetősen régi, de amikor megpróbáltam megtalálni a kedvenc módomat, ez a szál magasra került … és “meglepődtem, hogy senki sem említette:
perf stat -r 10 -B sleep 1
“perf” egy teljesítményelemző eszköz, amely a rendszermagban található az “tools / perf” alatt, és gyakran külön csomagként telepíthető (a “perf” a CentOS-ban és a “linux-tools” a Debianban / Ubuntuban). A Linux Kernal perf Wiki sokkal több információt tartalmaz róla.
A “perf stat” futtatása elég sok részletet tartalmaz, beleértve az átlagos végrehajtási időt közvetlenül a végén:
1.002248382 seconds time elapsed ( +- 0.01% )
megjegyzések
- mi az a
perf
? - @B Layer – szerkesztette válaszomat t o röviden ismertesse a következőt: ‘ perf ‘.
-
perf stat
most ” miatt panaszkodik. Lehet, hogy nincs jogosultsága statisztikák gyűjtésére. “, hacsak nem futtat néhány parancsot a , ami haszontalanná teszi minden olyan esetben, amikor nem ‘ nem teljesen a saját célgépe. - Elképesztő, köszönöm! Sokkal finomabb megoldás, mint
time
mások javasolják. Különösen aztime
nem alkalmazható a kódversenyes megoldások mérésére (mivel ‘ nem nyomtatja az időt ezredmásodpercekben és kevesebbben) , míg a megoldása igen.
Válasz
Egy kis shell funkció, amely korábban hozzáadható parancsok az idő mérésére:
tm() { local start=$(date +%s) $@ local exit_code=$? echo >&2 "took ~$(($(date +%s)-${start})) seconds. exited with ${exit_code}" return $exit_code }
Ezután használja a szkriptben vagy a parancssorban így:
tm the_original_command with all its parameters
Megjegyzések
- Érdemes ezredmásodperceket adni, megpróbálta az ilke
s=$(date +%s000)
-t, nem biztos ha működik. - @loretoparisi milliszekundumig, próbálkozzon a
date +%s%N
próbával. Lásd: serverfault.com/questions/151109/… - Ez nagyszerű, kivéve a biztonságosabbat használja az
"$@"
Válasz
#!/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..."
Megjegyzések
- Miben különbözik ez valójában a többi már adott választól, amelyek
date
-t használnak előtte és utána a szkriptet, és kiadja a köztük lévő különbséget?
Válasz
-
Csak használja
time [any command]
. Például:time sleep 1
valós idejű (azaz egy stopperóra időzített) ~ 1.000 és ~ 1.020 másodperc közötti alvás, az itt látható módon:$ time sleep 1 real 0m1.011s user 0m0.004s sys 0m0.000s
Milyen szép dolog. Bármelyik parancsot felteheti utána, és az eredményt szép, ember által olvasható formában adja ki. Nagyon szeretek az építések időzítésére használni. Például:
# time your "make" build time make # time your "Bazel" build time bazel build //path/to/some:target
… vagy git műveletekhez, amelyek potenciálisan valóban hosszú, így reális mentális elvárásokat tudok kialakítani:
# time how long it takes to pull from a massive repo when # I"m working from home during COVID-19. NB: `git pull` # is sooooo much slower than just pulling the one branch # you need with `git pull origin <branch>`, so just fetch # or pull what you need! time git pull origin master
-
A személyre szabottabb időzítési igényekhez ahol szükség lehet a kimenet manipulálására vagy más formákká alakítására, a bash , használja a belső
$SECONDS
változót. Itt van egy bemutató, beleértve a másodpercek más egységekké történő átalakítását, például lebegőpontos percek:Ne feledje, hogy az
dt_min
kerekítésre kerül0.01666666666...
(1 másodperc = annyi perc) és0.017
között ebben az esetben, mivel “aprintf
függvényt használom a kerekítéshez. Az alábbisleep 1;
részben megtalálhatod a szkripted futtatását és időzítését, de én csak 1 másodpercig alszom a bemutató kedvéért.Parancs:
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"
Kimenet:
dt_sec = 1; dt_min = 0.017
Kapcsolódó:
- körülbelül
bc
ésprintf
az itteni válaszomban: https://stackoverflow.com/questions/12722095/how-do-i-use-floating-point-division-in-bash/58479867#58479867 - Már nem emlékszem, hol tudtam meg először a
time
parancsot, de lehet, hogy a @Trudbert válasza itt .
Válasz
Csak a használatával bash azt is meg lehet mérni és kiszámolni a shell script egy részének időtartamát (vagy a teljes szkript eltelt ideje):
start=$SECONDS ... # do time consuming stuff end=$SECONDS
most már csak kinyomtathatja a különbséget:
echo "duration: $((end-start)) seconds."
ha csak növekményes időtartamra van szüksége, tegye:
echo "duration: $((SECONDS-start)) seconds elapsed.."
Az időtartamot egy változóban is elmentheti:
let diff=end-start
megjegyzések
- ^ EZ a válasz az embereknek. Vagy egyszerűbben: $ SECONDS a végén. ‘ egy BUILT-IN Bash változó. Az összes többi válasz csak extra munkát végez a kerék újrafeltalálásához …
- Ez csak a Marks korábbi válaszának megismétlése unix.stackexchange .com / a / 340156/155362 .
Válasz
Időzítési függvény a SECONDS
nem használ semmilyen külső parancsot:
time_it() { local start=$SECONDS ts ec printf -v ts "%(%Y-%m-%d_%H:%M:%S)T" -1 printf "%s\n" "$ts Starting $*" "$@"; 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" }
Például:
time_it sleep 5
ad
2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished sleep 5; elapsed = 5 seconds
Válasz
Használja a bash beépített idejét?
time: time [-p] PIPELINE Execute PIPELINE and print a summary of the real time, user CPU time, and system CPU time spent executing PIPELINE when it terminates. The return status is the return status of PIPELINE. The `-p" option prints the timing summary in a slightly different format. This uses the value of the TIMEFORMAT variable as the output format.
Példa:
TIMEFORMAT="The command took %Rs" time { sleep 0.1 }
Kimenet:
The command took 0.108s
Válasz
Itt található Alex variációja válaszok. Csak percek és másodpercek érdekelnek, de azt is szerettem volna, ha másképp lenne formázva. Tehát ezt tettem:
start=$(date +%s) end=$(date +%s) runtime=$(python -c "print "%u:%02u" % ((${end} - ${start})/60, (${end} - ${start})%60)")
megjegyzések
- Miért van a visszavonás? Van egy hibám?
- A
python
használata ehhez a számításhoz nekem is hibának tűnik, sajnálom, ember. Miért nem tudnak ‘ hívni aztime
-t, meghaladja rajtam.
Válasz
#!/bin/bash begin=$(date +"%s") Script termin=$(date +"%s") difftimelps=$(($termin-$begin)) echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
Válasz
Az elfogadott megoldás A (z) time
használatával a következőhöz ír: stderr
.
A times
parancsot használó div id = “ddc1bd7074”>
.
A$SECONDS
-t használó megoldásokból hiányzik a másodpercek alatti pontosság.
A többi megoldás külső programok, példáuldate
vagyperf
, amely nem hatékony.
Ha ezek bármelyikével jól áll, használja.
De ha hatékony megoldásra van szükség az idők megszerzéséhez milliszekundumos pontossággal és szükségük van rájuk változókká úgy, hogy a az eredeti kimenet zavartalan marad kombinálhatja a folyamat helyettesítését néhány átirányítással az time
körül, ami sokkal gyorsabb, mint a hívás külső programokat, és lehetővé teszi az átirányítást az időburkoló szkript körül, mint az eredeti parancsban / szkriptben.
# Preparations: Cmd=vgs # example of a program to be timed which is writing to stdout and stderr Cmd="eval { echo stdout; echo stderr >&2; sleep 0.1; }" # other example; replace with your own TIMEFORMAT="%3R %3U %3S" # make time output easy to parse
Válassza ki a következő változatok egyikét, elemezve a time
az Ön igényeinek megfelelő:
A legrövidebb változat, ahol a $Cmd
stdout
beírása stderr
és semmi stdout
:
read Elapsed User System < <({ time $Cmd 2>&3; } 3>&2 2>&1 >&3)
Hosszabb változat, amely megtartja eredeti stdout
és stderr
egymástól elkülönítve:
{ read Elapsed User System < <({ time $Cmd 2>&4; } 4>&2 2>&1 >&3); } 3>&1
A legbonyolultabb változat magában foglalja az extra fájlleírók bezárását úgy, hogy a $Cmd
-t úgy hívják meg, mintha ez az időzítő nem lenne körülötte, és lvm
parancsok, mint például a vgs
, nem panaszkodnak a kiszivárgott fájlleírókra:
{ read Elapsed User System < <({ time $Cmd 2>&4 4>&-; } 4>&2 2>&1 >&3 3>&-); } 3>&1
Ön akár lebegőpontos összeadást is képes hamisítani a bash
fájlban anélkül, hogy felhívná a bc
-t, ami sokkal lassabb lenne:
CPU=`printf %04d $((10#${User/.}+10#${System/.}))` # replace with your own postprocessing echo CPU ${CPU::-3}.${CPU: -3} s, Elapsed $Elapsed s >&2 # redirected independent of $Cmd
Lehetséges kimenetek a $Cmd
két példájával egy lassú CPU-n:
File descriptor 3 (/dev/pts/1) leaked on vgs invocation. Parent PID 10756: bash File descriptor 4 (/dev/pts/1) leaked on vgs invocation. Parent PID 10756: bash VG #PV #LV #SN Attr VSize VFree b3 3 24 0 wz--n- 1.31t 1.19t CPU 0.052 s, Elapsed 0.056 s
Vagy:
stdout stderr CPU 0.008 s, Elapsed 0.109 s