Unix'te zaman komutunun çıktısını bash değişkenine yönlendirilsin mi?


13

Sadece bir zaman komutunun çıktısını yakalamak istiyorum yani:

X=$(time ls)

veya

$(time ls) | grep real

Zaman fonksiyonu onu konsola tükürür. Bunu nasıl yaparım?

Yanıtlar:


12

X = `(süre ls) 2> & 1 | grep real`


Sadece alt kabuğa ihtiyacınız yok time; Dennis Williamson'ın cevabı bu açıdan daha iyi.
musiphil

11

Bakınız BashFAQ / 032 .

$ # captures output of command and time
$ time=$( TIMEFORMAT="%R"; { time ls; } 2>&1 )    # note the curly braces

$ # captures the time only, passes stdout through
$ exec 3>&1 4>&2
$ time=$(TIMEFORMAT="%R"; { time ls 1>&3 2>&4; } 2>&1)
bar baz
$ exec 3>&- 4>&-

Zaman TIMEFORMAT="%R", "gerçek" zaman olacak "0.000" gibi görünecektir .


bunun nasıl çalıştığını biraz açıklayabilir misiniz? Yıllardır bu kargo kült tarzı gibi bir pasaj kullanıyorum. Akış 3 ve 4 nedir? ve '-' ?
Sirex

1
@Sirex: Akış 3 ve 4, execmevcut dosya tanımlayıcılarını kullanarak cevabımdaki komut tarafından oluşturulan akışlardır . Mevcut tüm dosya tanımlayıcıları kullanılabilir. Akış 3 ve 4 , sırasıyla 1 ( stdout) ve 2 ( stderr) ' nin kopyalarıdır . Bu çıkış sağlar lsnormal geçmek stdoutve stderrçıkış ise 3 ve 4 aracılığı ile time(normal olarak gider için stderrorijinal yönlendirilir) stdout(1) ve daha sonra komut ikamesi kullanarak bir değişken yakalanan. Örneğimde gördüğünüz gibi, dosya adları barve bazterminale çıktı. ...
sonraki duyuruya kadar duraklatıldı.

1
... İşiniz bittiğinde, ekstra akışlar sondaki iz kullanılarak kapatılır -.
sonraki duyuruya kadar duraklatıldı.

4

Zaman çıktısını STDOUT yerine STDERR'a yazar. Daha da kötüsü, varsayılan olarak 'time' bir kabuk yerleşik komutudur, bu nedenle 'time ls 2> & 1' komutunu denerseniz '2> & 1' yalnızca 'ls' için geçerlidir.

Çözüm muhtemelen şöyle bir şey olurdu:

/usr/bin/time -f 'real %e' -o OUTPUT_FILE ls > /dev/null 2>&1<br>
REALTIME=$(cat OUTPUT_FILE | cut -f 2 -d ' ')

Bunu yapmanın daha süslü yolları var, ama bu açık / basit yol.


Bunu -o olmadan yapmak istiyorum. Düşündüğün süslü yöntemlerden birini gönderebilir misin :)?
David Doria

0

@Dennis Williamson'ın cevabı harika, ancak komutun çıktısını bir değişkene ve çıktısını timebaşka bir değişkene depolamanıza yardımcı olmaz . Bu aslında dosya tanımlayıcıları kullanarak mümkün değildir.

Bir programın ne kadar süreceğini kaydetmek istiyorsanız, bunu başlangıç ​​zamanını bitiş zamanından çıkararak yapabilirsiniz. Bir programın kaç milisaniye sürdüğünü gösteren basit bir örnek:

START_TIME=$(date +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(date +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"

Bu timekomut kadar doğru değildir , ancak çoğu bash betiği için mükemmel şekilde çalışmalıdır.

Maalesef Mac'in datekomutu %Nformatı desteklemiyor , ancak şunları yükleyebilir coreutils( brew install coreutils) ve kullanabilirsiniz gdate:

START_TIME=$(gdate +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(gdate +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
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.