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.