Zaman komutunun çıktısını Linux'ta bir dosyaya nasıl yeniden yönlendirebilirim?


202

Linux'taki zamanlama programları hakkında küçük bir soru: time komutu bir programın yürütme süresini ölçmeye izin verir:

[ed@lbox200 ~]$ time sleep 1

real    0m1.004s
user    0m0.000s
sys     0m0.004s

Hangi iyi çalışıyor. Ancak çıktıyı bir dosyaya yeniden yönlendirmeye çalışırsam başarısız olur.

[ed@lbox200 ~]$ time sleep 1 > time.txt

real    0m1.004s
user    0m0.001s
sys     0m0.004s

[ed@lbox200 ~]$ cat time.txt 
[ed@lbox200 ~]$ 

Dosya yazmak için -o seçeneği ile zaman başka uygulamalar olduğunu biliyorum ama sorum bu seçenekleri olmadan komut hakkında.

Baska öneri ?


3
Bir dosyada bash komut dosyası yazma yürütme Olası kopyası , ve ben bu tür ilk soru olduğuna ikna olmaktan çok uzak.
Jonathan Leffler

Yanıtlar:


268

Deneyin

{ time sleep 1 ; } 2> time.txt

"time" STDERR ve komutunuzu time.txt halinde birleştiren

Veya kullan

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

STDERR'ı "sleep" dan "sleep.stderr" dosyasına koyar ve yalnızca "time" dan STDERR "time.txt" dosyasına girer


2
Teşekkürler, bu tam olarak soruma cevap veriyor. Doğru anladıysam, zaman komutunun sonucu stderr?
ed82

8
Evet, ancak süslü parantez içine almalısınız, aksi takdirde yeniden yönlendirme timedeğerlendirilen komutun bir parçası olacaktır .
Ocak

5
@Daniel Dahili komut çıkışını her zaman ayrı ayrı yönlendirebilirsiniz (örn. {Time sleep 1 2> sleepStdErr.txt;} 2> time.txt) ve bu size yalnızca zaman çıkışını sağlayacaktır. Bunu bağımsız olarak almanın bir yolu olup olmadığından emin değilim.
gms7777

10
Zaman stdout okur grep gibi bir şey ile kullanmak istiyorsanız deneyin { time sleep 1; } 2>&1 | grep real. Bu, stderr'ı stdout'a gönderir ve grep daha sonra okuyabilir.
clayzermk1

9
unutma ';' '}' kapatmadan önce karakter, o olmadan ÇALIŞMAYACAK (yaptım ve ... merak neden çalışmıyor :))
THESorcerer

38

Sarın timeve zamanladığınız komutu bir grup parantez içine alın.

Örneğin, aşağıdaki zamanları lsve lszamanlamanın sonucunu ve sonuçlarını yazar outfile:

$ (time ls) > outfile 2>&1

Veya komutun çıktısını yakalanan çıktıdan ayırmak isterseniz time:

$ (time ls) > ls_results 2> time_results

12
Buraya bir alt kabuk tanıtmak gereksizdir.
Ocak

1
@ sampson-chen Bu sadece ls stderr için bir şey yazmadığı için çalışır değil mi? Eğer komut hem stdout hem de stderr yazıyorsa, 'zaman' çıktısını çalıştırılacak komuttan nasıl "ayırırsınız"?
David Doria

37

Basit. GNU timeyardımcı programının bunun için bir seçeneği vardır.

Ama emin zorunda değil kullandığınız kabuğun yerleşik kullanarak time, komut en azından bashyerleşiğine o seçeneği sunmaz! Bu yüzden timeyardımcı programın tam yolunu vermeniz gerekir :

/usr/bin/time -o time.txt sleep 1


14

Komutun hata çıktısını önemsiyorsanız, yerleşik zaman komutunu kullanırken bunları böyle ayırabilirsiniz.

{ time your_command 2> command.err ; } 2> time.log

veya

{ time your_command 2>1 ; } 2> time.log

Gördüğünüz gibi komutun hataları bir dosyaya gider (beri stderriçin kullanılır time).

Ne yazık ki başka bir tanıtıcıya (gibi 3>&2) gönderemezsiniz, çünkü bu artık{...}

Bununla birlikte, GNU zamanını kullanabiliyorsanız, @Tim Ludwinski'nin söylediklerini yapın.

\time -o time.log command

8

'Time' komutunun çıktısı hata çıktısı olduğundan, standart çıktı olarak yönlendirin, daha fazla işlem yapmak için daha sezgisel olacaktır.

{ time sleep 1; } 2>&1 |  cat > time.txt

6

Yerleşik bash yerine GNU saati kullanıyorsanız,

time -o outfile command

(Not: GNU saati, dahili bash'den biraz farklı formatlar).


1
Bu, teşekkürler. \time -o outfile commandYerleşik yerine GNU kullanmak için (`` ile) kullanabilirsiniz.
Mark

3
&>out time command >/dev/null

Senin durumunda

&>out time sleep 1 >/dev/null

sonra

cat out

3
Zarif fikir, ancak kabuğun yerleşik komutunu kullanmamasına yol açar. Yüklü gerçek bir timeikili yoksa , outgibi bir şey içerecektir bash: time: command not found.
14'te scy

Ayrıca GNU zamanının formatı bash yerleşikiyle aynı değildir ve otomatik ayrıştırma için sorunlara neden olur.
Guss

3

Ben kullanarak sona erdi:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • "A" ifadesinin eklendiği yer
  • "O" karakterine eklenecek dosya adıyla devam edildiğinde
  • "F", printf benzeri bir sözdizimiyle biçimlendirildiğinde
  • "% E", 0:00:00 üretir; saat: dakika: saniye
  • Ben bash "zaman" ayaklar altına ve aynı seçenekleri yok çünkü / usr / bin / time çağırmak zorunda kaldı
  • Ben sadece OP ile aynı şeyi değil, dosyaya çıktı almaya çalışıyordum

2
#!/bin/bash

set -e

_onexit() {
    [[ $TMPD ]] && rm -rf "$TMPD"
}

TMPD="$(mktemp -d)"
trap _onexit EXIT

_time_2() {
    "$@" 2>&3
}

_time_1() {
    time _time_2 "$@"
}

_time() {
    declare time_label="$1"
    shift
    exec 3>&2
    _time_1 "$@" 2>"$TMPD/timing.$time_label"
    echo "time[$time_label]"
    cat "$TMPD/timing.$time_label"
}

_time a _do_something
_time b _do_another_thing
_time c _finish_up

Bu, alt kabukları yumurtlamama avantajına sahiptir ve son boru hattı, stderr'ın gerçek stderr'e geri yüklenmesini sağlamıştır.


0

Orijinal işlemin stdout ve stderr öğesine dokunmak istemiyorsanız, stderr dosyasını dosya tanımlayıcı 3'e ve geriye yönlendirebilirsiniz:

$ { time { perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out

real    0m0.009s
user    0m0.004s
sys     0m0.000s

Çalışma zamanlarını izlemek için bir sarıcı (örneğin cronjobs için) için kullanabilirsiniz:

#!/bin/bash

echo "[$(date)]" "$@" >> /my/runtime.log

{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log

0

Eğer cshkullanıyorsanız:

/usr/bin/time --output=outfile -p $SHELL  -c 'your command'

Örneğin:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
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.