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.