Kabuktaki program yürütme süresini alın


407

Bir linux kabuğunda birkaç farklı koşulda bir şey yürütmek ve her yürütmenin yürütme süresini çıktılamak istiyorum.

Bunu yapacak bir perl veya python betiği yazabileceğimi biliyorum, ama kabuğunda yapabileceğim bir yol var mı? (bash olur)



Tickspencereler gibi almak mümkün mü?
freeforall tousez

Yanıtlar:


534

Yerleşik timeanahtar kelimeyi kullanın :

$ yardım süresi

zaman: zaman [-p] BORU HATTI
    PIPELINE'ı çalıştırın ve gerçek zamanlı, kullanıcı CPU zamanının bir özetini,
    ve sonlandığında PIPELINE yürütmek için harcanan sistem CPU zamanı.
    Dönüş durumu, BORU HATTI'nın dönüş durumudur. `-P 'seçeneği
    zamanlama özetini biraz farklı bir biçimde yazdırır. Bu kullanır
    çıkış biçimi olarak TIMEFORMAT değişkeninin değeri.

Misal:

$ time sleep 2
gerçek 0m2.009s
kullanıcı 0m0.000s
sys 0m0.004s

1
Bu nasıl bir komutta kullanılır time -p i=x; while read line; do x=x; done < /path/to/file.txt? While döngüsünden önce bir şey koymadıkça hemen 0.00 döndürür .. ne verir?
natli

Bu kötü 'zaman' versiyonu, bash yerleşik. harici 'zaman' komutu nerede?
Znik

6
@Znik, dene / usr / bin / time
Mark Rajcok

10
@natli: timeTüm bir boru hattını olduğu gibi zamanlayabilir (bir Bash anahtar kelimesi sayesinde ), birden fazla komutu zamanlamak için bir grup komutu ( { ...; ...; }) kullanmanız gerekir :time -p { i=x; while read line; do x=x; done < /path/to/file.txt; }
mklement0

2
Sisteminize kurduğunuz zamanın tüm sürümlerini görmek için şunları kullanabilirsiniztype -a time
spinup

120

Zamanı (1)time kullanarak yerleşik (Robert Gamble'ın bahsettiği) bash'tan çok daha ayrıntılı bilgi alabilirsiniz . Normalde bu ./usr/bin/time

Editörün notu: Kabuğunuzun anahtar kelimesi yerine harici yardımcı programı çağırdığınızdan emin olmak için aracı olarak çağırın . Bir olan POSIX zorunlu yarar , ancak destek için gereklidir tek seçenektir . : Belirli platformlar özgü, standart olmayan uzantılarını uygulamaya sahip eserler GNU 'ın (soru etiketli aşağıda gösterildiği gibi, faydatimetime /usr/bin/time
time-p
-vtime); BSD / macOS uygulaması -lbenzer çıktılar üretmek için kullanır - bkz man 1 time.

Ayrıntılı çıktı örneği:


$ /usr/bin/time -v sleep 1
       Command being timed: "sleep 1"
       User time (seconds): 0.00
       System time (seconds): 0.00
       Percent of CPU this job got: 1%
       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
       Average shared text size (kbytes): 0
       Average unshared data size (kbytes): 0
       Average stack size (kbytes): 0
       Average total size (kbytes): 0
       Maximum resident set size (kbytes): 0
       Average resident set size (kbytes): 0
       Major (requiring I/O) page faults: 0
       Minor (reclaiming a frame) page faults: 210
       Voluntary context switches: 2
       Involuntary context switches: 1
       Swaps: 0
       File system inputs: 0
       File system outputs: 0
       Socket messages sent: 0
       Socket messages received: 0
       Signals delivered: 0
       Page size (bytes): 4096
       Exit status: 0


2
hangi debian paketinin geleceğini bilemezdin? varsayılan olarak kurulmamış gibi görünüyor
Decıu

1
Gönderinize atıfta bulunuyordum Robert. Önerdiğiniz komut demek istemediğiniz sürece bash yerleşik değil mi?
grepsedawk

24
Şaşırtıcı bir şekilde, "zaman" adlı bir paketten kuruldu.
Paul Tomblin

2
/ Usr / bin / time çıktısı "0.00user 0.00system 0: 02.00deha fazla% 0 CPU (0avgtext + 0avgdata 0maxresident) k 0 girişler + 0 çıkışlar (0major + 172minor) sayfa hataları 0swaps"
Paul

4
@Nick: "sudo uygun-yükleme süresi".
Robert Gamble

79
#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

14
Çok daha basit bir yol var. Bash otomatik olarak özel $ SECONDS değişkenini hesaplar, ardından harici tarih komutuna dayalı yeniden hesaplama gerekmez. $ SECONDS değişkeni, bash betiğinin başladığında kaç saniye çalıştığını tutar. Bu değişken bazı özel özelliklere sahiptir. Bkz. Sayfa: D
Znik

Hem yukarıdaki hem de yöntemde yorum denedim. 1. Ben 'yasadışı değişken' hatası alıyorum ve 2. Ben 'tanımlanamayan değişken' olsun
DrBwts

45

Satır satır delta ölçümü için gnomon'u deneyin .

Zaman damgası bilgilerini başka bir komutun standart çıktısına yerleştirmek için moreutils's ts gibi bir komut satırı yardımcı programı. Bu kadar uzun süren şeylerin tarihsel bir kaydını almak istediğiniz uzun vadeli işlemler için kullanışlıdır.

Ayrıca , cücenin zaman damgasını kırmızı veya sarı ile vurgulayacağı bir uzunluk eşiği belirtmek için --highve / veya --mediumseçeneklerini de kullanabilirsiniz . Ve başka şeyler de yapabilirsiniz.

misal


3
Harika bir ipucu, ancak açık olmak gerekirse : bu, satır satır zamanlamalar için yararlıdır , ancak bu tür ince zamanlanmış zamanlamaların ek yükü, genel zamanlamaya önemli ölçüde katkıda bulunur .
mklement0

2
Müthiş yarar .. Paylaşım için teşekkürler
Kishan B

19

Daha hassas, kullanımı istesin %Nile date(ve kullanımını bc, çünkü fark için $(())sadece tamsayılar kolları).

Bunu nasıl yapacağınız aşağıda açıklanmıştır:

start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)

printf "Execution time: %.6f seconds" $dur

Misal:

start=$(date +%s.%N); \
  sleep 0.1s; \
  dur=$(echo "$(date +%s.%N) - $start" | bc); \
  printf "Execution time: %.6f seconds\n" $dur

Sonuç:

Execution time: 0.104623 seconds

15

Daha sonra hesaplamak için zamanları kullanmayı planlıyorsanız, zamandan tasarruf sağlayan kod çıktısını alma -fseçeneğini nasıl kullanacağınızı öğrenin . Kısa bir süre önce, bir sınıf öğrenci programının yürütme sürelerini almak ve sıralamak için kullandığım bazı kodlar:/usr/bin/time

fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...

Daha sonra tüm $timefiledosyaları birleştirdim ve çıktıyı bir Lua yorumlayıcısına aktardım . Aynı şeyi Python veya bash veya en sevdiğiniz sözdizimi ne olursa olsun yapabilirsiniz. Bu tekniği çok seviyorum.


Not: Tam yol /usr/bin/timegereklidir, çünkü which timeaksi halde size söyleyecektir, eğer basitçe çalıştırırsanız time, kabuğunuzun timeherhangi bir argümanı kabul etmeyen sürümünü çalıştıracaktır .
Kevin Dice


13

Yalnızca ikinciye kadar hassasiyete ihtiyacınız varsa $SECONDS, kabuğun çalıştığı saniye sayısını sayan yerleşik değişkeni kullanabilirsiniz .

while true; do
    start=$SECONDS
    some_long_running_command
    duration=$(( SECONDS - start ))
    echo "This run took $duration seconds"
    if some_condition; then break; fi
done

10

Kullanabilir timeve alt kabuk kullanabilirsiniz ():

time (
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
)

Veya aynı kabukta {}:

time {
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
}

İki özdeş kod parçacığı gönderdiniz. Orada farklı bir şey olması gerekiyordu.
stason

3
@StasBekman ilk önce (& )(yeni bağlam, alt kabuk ) ve diğer {& ile }(aynı kabuk, aynı bağlam) kullanarak doğru değildir
Eduardo Cuomo

Aha! İkisine çok sıkı bakıyordum ve farkı görmedim. {} Vs () 'yi açıkladığınız için teşekkür ederiz.
18'de stason

2

Yol

$ > g++ -lpthread perform.c -o per
$ > time ./per

çıktı >>

real    0m0.014s
user    0m0.010s
sys     0m0.002s

Kullanımına gerek yok -lphtreadya -oetiketleri. timeKabul edilen cevabın daha iyi açıkladığı komutu kullanmanız yeterlidir .
Dennis

7
Bu bir örnek oldu. Bu benim perform.c iş parçacığı vardır bu yüzden -lpthread gerekir ve basit kimlik için -o başına.
Robel Sharma

0

Muhtemelen basit bir yöntem (farklı kullanıcıların ihtiyaçlarını karşılamayabilir) kabuk PROMPT.it kullanımı bazı durumlarda yararlı olabilecek basit bir çözümdür. Aşağıdaki örnekte olduğu gibi bash komut istemi özelliğini kullanabilirsiniz:

PS1'i dışa aktar = '[\ t \ u @ \ h] \ $' 

Yukarıdaki komut kabuk komut istemini şu şekilde değiştirecektir:

[SS: DD: SS kullanıcı adı @ hostname] $ 

Kabuk istemine geri dönen bir komutu her çalıştırdığınızda (veya enter tuşuna bastığınızda), istem geçerli saati görüntüler.

notlar:
1) bir sonraki komutunuzu yazmadan önce bir süre beklediyseniz, bu zamanın dikkate alınması gerektiğini unutmayın, yani kabuk komut isteminde görüntülenen zaman, komut girdiğinizde değil, kabuk komut isteminin görüntülendiği zaman damgasıdır. bazı kullanıcılar bir sonraki komuta hazır olmadan önce yeni bir zaman damgası ile yeni bir istem almak için Enter tuşuna basmayı seçerler.
2) Bash istemini değiştirmek için kullanılabilecek başka seçenekler ve değiştiriciler de vardır, daha fazla ayrıntı için (man bash) bölümüne bakın.


Programın yürütüldüğü nokta değil, programın yürütme süresi.
Geno Chen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.