Haluan näyttää komentosarjan valmistumisajan.
Tällä hetkellä teen –
#!/bin/bash date ## echo the date at start # the script contents date ## echo the date at end
Tämä vain näyttää komentosarjan alkamis- ja lopetusajan. Onko se mahdollista näyttää hienorakeinen lähtö, kuten prosessorin aika / io-aika jne.?
Kommentit
- stackoverflow.com/questions/385408/ …
- Mielestäni nykyinen hyväksytty vastaus ei todellakaan riitä ajallisten vaihteluiden takia.
- @CiroSantilli 烏坎 事件 2016 六四 事件 法轮功 Luulen, että ehdotettu ketju ei vieläkään riitä poistamaan ajallisten tapahtumien vaikutuksia.
- Liittyy myös: stackoverflow.com/questions/5152858/… tai jonkin verran unix.stackexchange.com/questions/334145 / …
- On komento, jonka voit suorittaa ja sitten se ajastaa kaikki unix-komennot automaattisesti, unohditko ottaa käyttöön?
Vastaa
Jus t käytä time
, kun soitat komentosarjaa:
time yourscript.sh
kommentit
- Tämä tuottaa kolme kertaa:
real
,user
jasys
. Katso näiden merkitykset täältä . - ja ” todellinen ” on todennäköisesti mitä ihmiset haluavat tietää – ” Todellinen on seinäkello – aika puhelun alusta loppuun ”
- Onko olemassa tapaa siepata stdout tiedostoon? Esimerkiksi
time $( ... ) >> out.txt
- Voit tehdä tämän myös komentosarjojen kanssa komentorivillä, esim .:
time (command1 && command2)
- Tai hän voisi skriptissään vain tehdä: echo $ SECONDS olettaen, että se on bash ….
Vastaa
Jos time
ei ole vaihtoehto,
start=`date +%s` stuff end=`date +%s` runtime=$((end-start))
Kommentit
- Huomaa, että tämä toimii vain, jos et ’ tarvitse toissijaista tarkkuutta. Joillekin käyttötavoille, jotka voivat olla hyväksyttäviä , muille ei. Hieman paremman tarkkuuden saavuttamiseksi (’ kutsutaan edelleen
date
esimerkiksi kahdesti, joten saatat olla kohdassa paras millisekunnin tarkkuus käytännössä ja todennäköisesti vähemmän), yritä käyttäädate +%s.%N
. (%N
on nanosekuntia, koska koko sekunti .) - @ChrisH Oh. Hyvä osoittaa se; bashin aritmeettinen laajennus on vain kokonaisluku. Näen kaksi obvi ous vaihtoehtoja; joko ojaa päivämäärä muotoilumerkkijonossa (ja käsittele tuloksena olevaa arvoa nanosekunteina aikakaudesta lähtien), joten käytä
date +%s%N
tai käytä jotain kykenevämpää kutenbc
laskea todellinen ajonaika kahdesta arvosta, kuten jwchew ehdottaa. Silti minusta tämä lähestymistapa on epäoptimaalinen tapa tehdä se;time
on huomattavasti parempi, jos saatavilla, yllä esitetyistä syistä. - Asenna vain
bc
ja tee tämä seuraavasti:runtime=$( echo "$end - $start" | bc -l )
- Jos komentosarjasi kestää useita minuutteja, käytä:
echo "Duration: $((($(date +%s)-$start)/60)) minutes
- Seuraava osoitteeseen @ rubo77 kommentti, jos komentosarjasi kestää useita tunteja, käytä
hours=$((runtime / 3600)); minutes=$(( (runtime % 3600) / 60 )); seconds=$(( (runtime % 3600) % 60 )); echo "Runtime: $hours:$minutes:$seconds (hh:mm:ss)"
vastausta
Soita vain times
ilman argumentteja poistutessasi komentosarjastasi.
ksh
tai zsh
, voit käyttää sen sijaan myös time
. zsh
, time
antaa sinulle myös seinäkellonajan käyttäjän ja lisäksi system suorittimen aika.
Voit säilyttää komentosarjan poistumistilan tekemällä sen:
ret=$?; times; exit "$ret"
Tai sinä voi myös lisätä ansaan EXIT
:
trap times EXIT
Tällä tavalla aikoja kutsutaan aina, kun kuori poistuu ja poistumistila säilyy.
$ 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
Huomaa myös, että kaikki bash
, ksh
ja zsh
on $SECONDS
-muuttuja, joka kasvaa automaattisesti sekunnin välein. Sekä zsh
että ksh93
muuttujasta voidaan tehdä myös liukuluku (typeset -F SECONDS
) tarkkuuden lisäämiseksi. Tämä on vain seinäkello, ei suorittimen aikaa.
Kommentit
- Että $ SECONDS-muuttuja on erittäin hyödyllinen, kiitos! > Poistaako lähestymistapasi ajallisten tapahtumien vaikutukset? – – Mielestäni lähestymistapasi on lähellä aiemmin esitettyä
time
-tapaa.- – Mielestäni MATLAB-koodissa esitetystätimeit
-lähestymistavasta voi olla hyötyä. - Hei, @St é Phane Chazelas. Huomasin, että
times
ei anna ’ t antaa seinälle aikaa, eikö? esimerkiksibash -c 'trap times EXIT;sleep 2'
- @Binarus, kyllä, tämä ominaisuus tulee ksh: stä. Päinvastoin kuin ksh93 / zsh, bashin lisäksi, joka ei tue liukulukua, se ’ rikkoutuu myös siinä, että kun asetat SECONDS-arvoksi 0, se muuttuu arvoksi 0 0 sekunniksi 1 sekunnin kuluttua ( koska se ottaa huomioon vain
time()
-tuloksen, jolla on vain täysi toinen tarkkuus). - @Binarus, ei sitä, että ’ s välillä 0 – 1. Jos asetat SECONDS-arvoksi 0 klo 12: 00: 00.000, se muuttuu yhdeksi sekunniksi myöhemmin. Mutta jos asetat sen 12: 00: 00.999, se muuttuu yhdeksi millisekunniksi myöhemmin. Mutta kyllä, olen samaa mieltä siitä, että sillä ei todennäköisesti ’ ole väliä väliä käytännössä, jos sinulla ’ ei ole muutaman sekunnin tarkkuutta.
vastaus
I ”vähän myöhässä bandwagoniin, mutta halusin lähettää ratkaisuni (sekunnin tarkkuudesta) ), jos toiset törmäävät tähän ketjuun etsimällä. Tulos on päivien, tuntien, minuuttien ja viimeisten sekuntien muoto:
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
Toivottavasti joku siellä se pitää tätä hyödyllisenä!
Kommentit
- Luulen, ettei ole muuta (vain bash) tapaa kuin käyttää ’ bc ’ tehdä laskelmat. BTW todella hyvä komentosarja;)
- Varo, että FreeBSD ’ s
date
ei tue sekunnin tarkkuutta ja lisää vain kirjaimellisen ”N
” aikaleimaan. - Erittäin mukava käsikirjoitus, mutta bash ei ole ’ t käsittele alaosaa. Olen myös oppinut, että / 1 bc: ssä nauhoittaa sen tehokkaasti, joten lisäsin @ / 1 @ $ ds -laskentaan, ja se näyttää nyt erittäin hienoja juttuja!
- bc tukee moduloa:
dt2=$(echo "$dt%86400" | bc)
. Sanon vain … BTW mieluummin muotodt2=$(bc <<< "${dt}%86400")
, mutta se, että ’ on täysin henkilökohtainen. - En ’ en tiedä vielä mitään
bc
, mutta jakaminen86400
tekee minut epäluuloiseksi seuraava syy: On päiviä, joissa ei ole 86400 sekuntia, esimerkiksi päivät, jolloin aika vaihdetaan DST: stä normaaliaikaan ja päinvastoin, tai päivät, joissa sekuntia on harppaus. Jos tällaiset päivät ovat osa laskettavaa aikajaksoa, eli ne ovatres1
–res2
(nämä arvot mukaan lukien) välillä, komentosarjasi epäonnistuu todennäköisesti.
Vastaa
Menetelmäni kohteelle bash
:
# Reset BASH time counter SECONDS=0 # # do stuff # ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
Kommentit
- Tämä näyttää kuluneen ajan, mutta ei ’ t näytä ” hienorakeinen lähtö, kuten prosessorin aika, I / O-aika ” kuten kysymys kysytään.
- Ne, jotka etsivät vastausta esitettyyn kysymykseen, pitävät tätä ratkaisua todennäköisesti hyödyllisenä. Kommenttisi olisi paremmin osoitettu OP-kysymykseen.
Vastaa
Henkilökohtaisesti haluan kääri kaikki komentokoodi joissakin ”main” -funktioissa, kuten:
main () { echo running ... } # stuff ... # calling the function at the very end of the script time main
Huomaa kuinka helppoa on käyttää time
-komentoa tässä skenaariossa. Ilmeisesti et mittaa tarkkaa aikaa, mukaan lukien komentosarjan jäsentämisaika, mutta mielestäni se on riittävän tarkka useimmissa tilanteissa.
Kommentit
- Loistava ratkaisu, ei vaadi ylimääräisiä työkaluja ja on itsenäinen.
Vastaa
#!/bin/bash start=$(date +%s.%N) # HERE BE CODE end=$(date +%s.%N) runtime=$(python -c "print(${end} - ${start})") echo "Runtime was $runtime"
Kyllä, tämä kutsuu Pythonia, mutta jos pystyt elämään sen kanssa, tämä on varsin mukava, lyhyt ratkaisu.
Kommentit
- Varo, että kyseisen
python
-komennon suorittaminen alikuoressa ja sen lähdön lukeminen vie useita miljoonia nanosekunteja useimmissa nykyisissä järjestelmissä. Sama käynnissädate
. - ” Useat miljoonat nanosekunnit ” on useita millisekunteja Ihmiset, jotka ajoittavat bash-komentosarjoja, eivät yleensä ole siitä kovin huolissaan (paitsi jos he käyttävät useita miljardeja komentosarjoja megasekunnissa).
- Huomaa myös, että vaikka Laskenta tehdään python-prosessissa, arvot kerättiin kokonaan ennen pythonin käynnistämistä. Komentosarjan suoritusaika mitataan oikein ilman ” miljoonia nanosekunteja ” yleiskustannuksia.
-
time main
yllä on paljon puhtaampaa …kyllä, voimme elää paljon huonontumista, mutta se ’ on parempi tapa ilman, että ’ pysyvät insinööreinä! -
$(echo $end - $start | bc)
tekee saman asian ilman pythonia
Vastaa
Tämä kysymys on melko vanha, mutta yrittäessäni löytää suosikkini tapani tehdä tämä säie nousi korkealle … ja minä yllättyin, ettei kukaan maininnut sitä:
perf stat -r 10 -B sleep 1
”perf” on suorituskyvyn analysointityökalu, joka sisältyy ytimen kohtaan ”tools / perf” ja on usein asennettavissa erillisenä pakettina (”perf” CentOS: ssa ja ”linux-tools” Debianissa / Ubuntussa). Linux Kernal perf Wikissä on paljon enemmän tietoa siitä.
”perf stat”: n suorittaminen antaa melko vähän yksityiskohtia, mukaan lukien keskimääräinen suoritusaika aivan lopussa:
1.002248382 seconds time elapsed ( +- 0.01% )
kommentit
- Mikä on
perf
? - @B Layer – muokkasi vastaustani t o anna lyhyt kuvaus ’ perf ’.
-
perf stat
valittaa nyt ” Sinulla ei ehkä ole lupaa kerätä tilastoja. ” ellet aja komentojasudo
, mikä tekee siitä hyödyttömän kaikissa tilanteissa, joissa et ’ omista täysin kohdekonetta. - Hämmästyttävä, kiitos! Paljon hienorakeisempaa ratkaisua kuin
time
muut ehdottavat. Erityisestitime
ei sovellu koodikilpailuratkaisujen mittaamiseen (koska se ei tulosta ’ t millisekunteina tai vähemmän) , kun taas ratkaisusi tekee.
Vastaa
Pieni kuoritoiminto, joka voidaan lisätä ennen komennot aikansa mittaamiseksi:
tm() { local start=$(date +%s) $@ local exit_code=$? echo >&2 "took ~$(($(date +%s)-${start})) seconds. exited with ${exit_code}" return $exit_code }
Käytä sitten komentosarjassa tai komentorivillä näin:
tm the_original_command with all its parameters
Kommentit
- Kannattaa lisätä millisekunteja, yritti ilke
s=$(date +%s000)
, en ole varma jos se toimii. - @loretoparisi millisekunnin ajan, voit kokeilla
date +%s%N
. Katso serverfault.com/questions/151109/… - Tämä on hieno, paitsi turvallisempi käytä
"$@"
Vastaa
#!/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..."
kommentit
- Miten tämä todella eroaa muista jo annetuista vastauksista, joissa käytetään
date
ennen ja jälkeen komentosarja ja antaa niiden välinen ero?
Vastaa
-
Vain käytä
time [any command]
. Esimerkki:time sleep 1
nukkuu reaaliajassa (ts. Sekuntikellon ajastamana) ~ 1000 – ~ 1,020 sekuntia, kuten tässä näytetään:$ time sleep 1 real 0m1.011s user 0m0.004s sys 0m0.000s
Mikä kaunis asia. Voit laittaa minkä tahansa komennon sen jälkeen, ja se tuottaa tuloksen mukavassa, ihmisten luettavassa muodossa. Haluan todella käyttää sitä rakennusten ajoitukseen. Esimerkki:
# time your "make" build time make # time your "Bazel" build time bazel build //path/to/some:target
… tai git-operaatioille, jotka voivat olla todella pitkä, joten voin kehittää realistisia henkisiä odotuksia:
# 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
-
Lisää räätälöityjä ajoitustarpeita varten missä sinun on ehkä käsiteltävä lähtöä tai muunnettava se muuhun muotoon, bash , käytä sisäistä muuttujaa
$SECONDS
. Tässä on esittely, mukaan lukien näiden sekuntien muuntaminen muiksi yksiköiksi, kuten liukuluku minuutteiksi:Huomaa, että
dt_min
pyöristetään arvosta0.01666666666...
(1 sekunti = niin monta minuuttia) arvoon0.017
tässä tapauksessa koska ”käytän pyöristykseenprintf
-funktiota. Alla olevastasleep 1;
osasta kutsutaan komentosarjaasi ajamaan, mutta nukun vain yhden sekunnin ajan tämän esittelyn vuoksi.Komento:
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"
Tulos:
dt_sec = 1; dt_min = 0.017
Liittyvä:
- Lue lisää noin
bc
japrintf
vastauksestani: https://stackoverflow.com/questions/12722095/how-do-i-use-floating-point-division-in-bash/58479867#58479867 - En muista, mistä ensin sain tietää
time
-komennosta, mutta se on saattanut olla @Trudbert vastaus täällä .
Vastaa
Käytä vain vain bash on myös mahdollista mitata ja laskea kuoriskriptin osan kesto (tai koko komentosarjan kulunut aika):
start=$SECONDS ... # do time consuming stuff end=$SECONDS
voit nyt joko tulostaa eron:
echo "duration: $((end-start)) seconds."
jos tarvitset vain inkrementaalista kestoa, tee:
echo "duration: $((SECONDS-start)) seconds elapsed.."
Voit tallentaa keston myös muuttujaan:
let diff=end-start
kommentit
- ^ TÄMÄ on vastaus ihmisille. Tai yksinkertaisemmin: $ SECONDS lopussa. Se ’ on BUILT-IN Bash -muuttuja. Kaikki muut vastaukset tekevät vain ylimääräistä työtä keksimään tämä pyörä uudelleen.
- Tämä on vain toistoa Marksin aikaisemmasta vastauksesta unix.stackexchange .com / a / 340156/155362 .
vastaus
Ajoitustoiminto perustuu id = ”9d6089280a”>
, rajoitettu vain toisen tason rakeisuuteen, ei käytä ulkoisia komentoja:
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" }
Esimerkki:
time_it sleep 5
antaa
2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished sleep 5; elapsed = 5 seconds
vastaus
Käytä sisäänrakennettua bash-aikaa?
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.
Esimerkki:
TIMEFORMAT="The command took %Rs" time { sleep 0.1 }
Tulos:
The command took 0.108s
Vastaa
Tässä Alexin muunnelma ”Vastaus. Minusta välittävät vain minuutit ja sekunnit, mutta halusin myös, että se muotoiltiin eri tavalla. Joten tein tämän:
start=$(date +%s) end=$(date +%s) runtime=$(python -c "print "%u:%02u" % ((${end} - ${start})/60, (${end} - ${start})%60)")
Kommentit
- Miksi downvote? Onko minulla vika?
-
python
: n käyttäminen laskutoimituksessa näyttää minulta myös virhettä, anteeksi mies. Miksi ihmiset ’ eivät voi vain soittaa numeroontime
, on minun ulkopuolella.
Vastaa
#!/bin/bash begin=$(date +"%s") Script termin=$(date +"%s") difftimelps=$(($termin-$begin)) echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
vastaus
Hyväksytty ratkaisu käyttämällä time
kirjoittaa stderr
.
Ratkaisu, joka käyttää times
, kirjoittaa osoitteeseen stdout
.
Ratkaisuista, jotka käyttävät $SECONDS
, puuttuu toisen sekunnin tarkkuus.
Muihin ratkaisuihin kuuluu ulkoisten ohjelmien, kuten date
tai perf
, joka ei ole tehokasta.
Jos jokin näistä on kunnossa, käytä sitä.
Mutta jos tarvitset tehokkaan ratkaisun saadaksesi ajat millisekunnin tarkkuudella ja tarvitsevat ne muuttujiksi siten, että alkuperäinen lähtö pysyy häiriöttömänä voit yhdistää prosessin korvaamisen joihinkin uudelleenohjauksiin time
ympärille, mikä on paljon nopeampi kuin soittaminen ulkoiset ohjelmat ja sallii uudelleenohjauksen ajoituksen käärintäkomentosarjan ympärille kuten alkuperäisessä komennossa / komentosarjassa.
# 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
Valitse jokin seuraavista muunnoksista, jotka jäsennetään time
sinulle sopiva:
Lyhin muunnos, johon stdout
/ $Cmd
kirjoitetaan osoitteeseen stderr
eikä mitään stdout
:
read Elapsed User System < <({ time $Cmd 2>&3; } 3>&2 2>&1 >&3)
Pidempi vaihtoehto, joka pitää alkuperäinen stdout
ja stderr
erillään toisistaan:
{ read Elapsed User System < <({ time $Cmd 2>&4; } 4>&2 2>&1 >&3); } 3>&1
Monimutkaisin variantti sisältää ylimääräisten tiedostokuvaajien sulkemisen siten, että $Cmd
kutsutaan ikään kuin ilman tätä ajoituspakettia sen ympärille ja lvm
-komennot, kuten vgs
, eivät valita vuotaneista tiedostokuvaajista:
{ read Elapsed User System < <({ time $Cmd 2>&4 4>&-; } 4>&2 2>&1 >&3 3>&-); } 3>&1
Sinä voi jopa väärentää kelluvan pisteen lisäyksen hakemistossa bash
soittamatta bc
, mikä olisi paljon hitaampaa:
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
Mahdolliset lähdöt kahdella esimerkillä $Cmd
hitaalla suorittimella:
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
Tai:
stdout stderr CPU 0.008 s, Elapsed 0.109 s