Bagaimana cara mengarahkan output perintah waktu ke file di Linux?

202

Hanya sedikit pertanyaan tentang pengaturan waktu program di Linux: perintah waktu memungkinkan untuk mengukur waktu eksekusi suatu program:

[ed@lbox200 ~]$ time sleep 1

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

Itu bekerja dengan baik. Tetapi jika saya mencoba mengalihkan output ke file, itu gagal.

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

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

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

Saya tahu ada implementasi waktu lain dengan opsi -o untuk menulis file tetapi pertanyaan saya adalah tentang perintah tanpa opsi itu.

Ada saran?

ed82
sumber
3
Kemungkinan duplikat penulisan bash script mengeksekusi waktu dalam file , dan saya jauh dari yakin bahwa ini adalah pertanyaan pertama seperti itu.
Jonathan Leffler
1
Ini adalah duplikat dari stackoverflow.com/questions/2408981/…
codeforester

Jawaban:

266

Mencoba

{ time sleep 1 ; } 2> time.txt

yang menggabungkan STDERR dari "waktu" dan perintah Anda ke time.txt

Atau gunakan

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

yang menempatkan STDERR dari "sleep" ke dalam file "sleep.stderr" dan hanya STDERR dari "time" yang masuk ke "time.txt"

Januari
sumber
2
Terima kasih, itu menjawab pertanyaan saya. Jika saya mengerti dengan benar, hasil perintah waktu dapat diperoleh dari stderr?
ed82
7
Ya, tetapi Anda harus meletakkannya di kurung keriting, jika tidak pengalihan akan menjadi bagian dari perintah yang timemengevaluasi.
Januari
5
@Daniel Anda selalu dapat mengarahkan output perintah internal secara terpisah (yaitu {time sleep 1 2> sleepStdErr.txt;} 2> time.txt) dan itu akan membuat Anda hanya output waktu. Saya tidak yakin apakah ada cara untuk mendapatkannya secara mandiri.
gms7777
10
Jika Anda ingin menggunakan waktu dengan sesuatu seperti grep yang berbunyi dari stdout coba { time sleep 1; } 2>&1 | grep real. Ini mengirimkan stderr ke stdout yang mana grep dapat membaca.
clayzermk1
9
JANGAN lupakan ';' karakter sebelum menutup '}', itu TIDAK akan bekerja tanpa (saya lakukan, dan ... bertanya-tanya mengapa tidak bekerja :))
THESorcerer
38

Bungkus timedan perintah Anda mengatur waktu dalam satu set kurung.

Misalnya, waktu berikut lsdan tuliskan hasil lsdan hasil waktunya ke outfile:

$ (time ls) > outfile 2>&1

Atau, jika Anda ingin memisahkan output dari perintah dari output yang diambil dari time:

$ (time ls) > ls_results 2> time_results
sampson-chen
sumber
12
Tidak perlu memperkenalkan subkulit di sini.
Januari
1
@ sampson-chen Itu hanya bekerja karena ls tidak menulis apa pun untuk stderr kan? Bagaimana Anda "memisahkan" output dari 'waktu' dari perintah yang akan dijalankan jika perintah menulis ke stdout dan stderr?
David Doria
36

Sederhana. timeUtilitas GNU memiliki opsi untuk itu.

Tetapi Anda harus memastikan bahwa Anda tidak menggunakan timeperintah builtin shell Anda , setidaknya bashbuiltin tidak menyediakan opsi itu! Itu sebabnya Anda perlu memberikan path lengkap dari timeutilitas:

/usr/bin/time -o time.txt sleep 1
cmaster - mengembalikan monica
sumber
Anda juga dapat menggunakan non-built-in tanpa menentukan path lengkap: stackoverflow.com/questions/29540540/…
Ciro Santilli 郝海东 冠状 病 六四 六四 事件 法轮功
14

Jika Anda peduli dengan output kesalahan perintah, Anda dapat memisahkannya seperti ini saat masih menggunakan perintah waktu bawaan.

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

atau

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

Ketika Anda melihat kesalahan perintah pergi ke file (sejak stderrdigunakan untuk time).

Sayangnya Anda tidak dapat mengirimnya ke pegangan lain (seperti 3>&2) karena itu tidak akan ada lagi di luar{...}

Yang mengatakan, jika Anda dapat menggunakan waktu GNU, lakukan saja apa yang dikatakan @Tim Ludwinski.

\time -o time.log command
Menandai
sumber
8

Karena output dari perintah 'waktu' adalah output kesalahan, redirect sebagai output standar akan lebih intuitif untuk melakukan pemrosesan lebih lanjut.

{ time sleep 1; } 2>&1 |  cat > time.txt
jaycee xu
sumber
6

Jika Anda menggunakan waktu GNU alih-alih bash built-in, coba

time -o outfile command

(Catatan: Format waktu GNU sedikit berbeda dari bash built-in).

Tim Ludwinski
sumber
1
Ini terima kasih Dan Anda dapat menggunakan \time -o outfile command(dengan ``) untuk menggunakan GNU alih-alih bawaan.
Tandai
3
&>out time command >/dev/null

dalam kasus Anda

&>out time sleep 1 >/dev/null

kemudian

cat out
alinsoar
sumber
3
Ide yang elegan, tetapi mengarah ke shell yang tidak menggunakan perintah bawaannya. Jika Anda tidak memiliki real timebiner diinstal, outakan berisi sesuatu seperti bash: time: command not found.
scy
Juga format untuk waktu GNU tidak sama dengan bash builtin, menyebabkan masalah untuk penguraian otomatis.
Guss
3

Saya akhirnya menggunakan:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • Di mana "a" ditambahkan
  • Di mana "o" diproses oleh nama file untuk ditambahkan
  • Di mana "f" adalah format dengan sintaks seperti printf
  • Di mana "% E" menghasilkan 0:00:00; jam: menit: detik
  • Saya harus memanggil / usr / bin / time karena "waktu" bash menginjak-injaknya dan tidak memiliki opsi yang sama
  • Saya hanya mencoba untuk mendapatkan output ke file, bukan hal yang sama dengan OP
Lokal
sumber
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

Ini memiliki keuntungan tidak memunculkan subkulit, dan pipa akhir telah mengembalikannya ke stderr yang sebenarnya.

Adam Heath
sumber
0

Jika Anda tidak ingin menyentuh stdout dan stderr proses asli, Anda dapat mengarahkan stderr ke file descriptor 3 dan kembali:

$ { 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

Anda bisa menggunakannya untuk pembungkus (mis. Untuk cronjobs) untuk memantau runtime:

#!/bin/bash

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

{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log
Tobias Gödderz
sumber
0

Jika Anda menggunakan, cshAnda dapat menggunakan:

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

Sebagai contoh:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
Leo Cardona
sumber