Untuk mengetahui berapa lama operasi tertentu dalam skrip Bash (v4 +), saya ingin mengurai output dari time
perintah "secara terpisah" dan (akhirnya) menangkapnya dalam variabel Bash ( let VARNAME=...
).
Sekarang, saya menggunakan time -f '%e' ...
(atau lebih tepatnya command time -f '%e' ...
karena Bash built-in), tetapi karena saya sudah mengarahkan output dari perintah yang dieksekusi, saya benar-benar bingung bagaimana saya akan menangkap output dari time
perintah. Pada dasarnya masalah di sini adalah untuk memisahkan output dari time
output dari perintah yang dieksekusi.
Yang saya inginkan adalah fungsionalitas menghitung jumlah waktu dalam detik (bilangan bulat) antara memulai perintah dan penyelesaiannya. Itu tidak harus menjadi time
perintah atau masing-masing built-in.
Sunting: mengingat dua jawaban yang berguna di bawah ini, saya ingin menambahkan dua klarifikasi.
- Saya tidak ingin membuang output dari perintah yang dieksekusi, tetapi tidak masalah apakah itu berakhir pada stdout atau stderr.
- Saya lebih suka pendekatan langsung daripada yang tidak langsung (yaitu menangkap output secara langsung sebagai lawan menyimpannya dalam file perantara).
Solusi menggunakan date
sejauh ini mendekati apa yang saya inginkan.
sumber
fork()
,execvp()
danwait3()/wait4()
. Inilah yang akhirnya dilakukan oleh waktu dan teman-teman. Saya tidak mengetahui cara simle untuk melakukannya di bash / perl tanpa mengarahkan ke file atau pendekatan serupa.Jawaban:
Untuk mendapatkan output dari
time
var gunakan yang berikut ini:Anda juga dapat meminta satu jenis waktu saja, mis. Utime:
Untuk mendapatkan waktu yang juga bisa Anda gunakan
date +%s.%N
, jadi ambil sebelum dan sesudah eksekusi dan hitung perbedaannya:sumber
DIFF=$((END-START))
, memanfaatkan ekspresi aritmatika. :) ... Terima kasih atas jawabannya. +1.%N
dalam kode binfalse), Anda perlubc
atau perhitungan yang lebih bagus.time (cmd) 2> something
pekerjaan mengarahkan ulang output waktufile
, itu tidak dimaksudkan untuk (sesuai dokumentasi), tidak di shell lain di manatime
kata kunci dan dapat dianggap sebagai bug . Saya tidak akan bergantung pada itu karena mungkin tidak berfungsi di versi masa depanbash
.Dalam bash, output dari
time
konstruk pergi ke kesalahan standar, dan Anda bisa mengarahkan kesalahan standar dari pipa yang terpengaruh. Jadi mari kita mulai dengan perintah yang menulis ke output dan error streamas nya:sh -c 'echo out; echo 1>&2 err'
. Agar tidak mencampur aliran kesalahan perintah dengan output daritime
, kita dapat sementara mengalihkan aliran kesalahan perintah ke deskriptor file yang berbeda:Ini menulis
out
ke fd 1,err
ke fd 3, dan waktu ke fd 2:Akan lebih menyenangkan untuk memiliki
err
pada fd 2 dan waktu pada fd 3, jadi kami menukar mereka, yang rumit karena tidak ada cara langsung untuk menukar dua deskriptor file:Ini menunjukkan bagaimana Anda dapat memposting proses output dari perintah, tetapi jika Anda ingin menangkap output dari perintah dan waktu, Anda harus bekerja lebih keras. Menggunakan file sementara adalah salah satu solusinya. Sebenarnya, itu satu-satunya solusi yang andal jika Anda perlu menangkap kesalahan standar perintah dan output standarnya. Tetapi sebaliknya, Anda bisa menangkap seluruh output dan memanfaatkan fakta yang
time
memiliki format yang dapat diprediksi (jika Anda menggunakantime -p
untuk mendapatkan format POSIX atauTIMEFORMAT
variabel spesifik-bash ).Jika Anda hanya peduli dengan waktu jam dinding, menjalankan
date
sebelum dan sesudah adalah solusi sederhana (jika sedikit lebih tidak tepat karena waktu ekstra yang dihabiskan untuk memuat perintah eksternal).sumber
Dengan waktu, output perintah keluar pada stdout dan waktu keluar pada stderr. Jadi, untuk memisahkannya, Anda dapat melakukan:
Tapi, sekarang waktunya ada dalam file. Saya tidak berpikir Bash dapat menempatkan stderr dalam suatu variabel secara langsung. Jika Anda tidak keberatan mengarahkan output perintah di suatu tempat, Anda dapat melakukan:
Ketika Anda melakukan ini, keluaran perintah ini akan di
outputfile
dan waktu yang dibutuhkan untuk menjalankan akan di$FOO
.sumber
time
menulis ke stderr, tetapi saya tidak menyadari bahwa itu akan menggabungkan stdout dan stderr dari perintah yang dieksekusi ke dalam stdout. Tetapi umumnya tidak ada metode langsung (yaitu tanpa file perantara)? +1.time
tidak menggabungkan perintahstdout
danstderr
. Cara saya menunjukkan diasumsikan bahwa Anda hanya perlu keluaran stdout perintah. Karenabash
hanya akan menyimpan apa yang keluarstdout
, Anda harus mengarahkan ulang. Jika Anda dapat dengan aman menjatuhkan stderr perintah Anda: waktu akan selalu berada di baris terakhir stderr. Jika Anda memang membutuhkan kedua aliran output perintah Anda, saya sarankan membungkusnya dalam skrip lain.Jika Anda berada di
bash
(dan tidaksh
) dan Anda TIDAK perlu akurasi sub-detik, Anda dapat melewatkan panggilan untukdate
sepenuhnya dan melakukannya tanpa memunculkan proses tambahan, tanpa harus memisahkan output gabungan, dan tanpa harus menangkap dan mengurai output dari perintah apa pun:sumber
Untuk tujuan itu mungkin lebih baik menggunakan
times
(daripadatime
) dibash
mana mencetak akumulasi pengguna dan waktu sistem untuk shell dan untuk proses yang dijalankan dari shell, contoh gunakan:Lihat:
help -m times
untuk info lebih lanjut.sumber
Dalam Menyatukan semua respons sebelumnya, saat dalam OSX
Anda bisa suka
sumber
Instal
/bin/time
(mis.pacman -S time
)Jadi alih-alih kesalahan saat mencoba
-f
menandai:Anda benar-benar dapat menggunakannya:
Dan dapatkan yang Anda inginkan - waktu dalam variabel (misalnya penggunaan
%e
untuk waktu yang telah berlalu, untuk pemeriksaan opsi lainman time
):sumber
/usr/bin/time
pada banyak sistemtime
adalah shell builtin di Bash (dan mungkin shell lain) tetapi selama path ketime
executable adaPATH
, kita dapat menggunakancommand time
untuk memastikan kita menjalankan perintah eksternal sebagai lawan dari builtin.Sama seperti kepala ketika bekerja dengan pernyataan di atas dan terutama mengingat jawaban Grzegorz dalam pikiran. Saya terkejut melihat pada sistem Xenial Ubuntu 16.04 saya dua hasil ini:
Saya tidak memiliki alias alias apa pun, jadi saya tidak tahu mengapa ini terjadi.
sumber
time
juga merupakan shell bawaan.command
, jika Anda ingin memastikan Anda menjalankan builtin, gunakanbuiltin
. Tidak ada keajaiban di sini. Gunakanhelp
untuk mencari tahu perintah yang tersedia atautype <command>
untuk mencari tahu apa jenisnya<command>
(misalnya builtin, perintah eksternal, fungsi atau alias).command
perintah itu. Yang mana fakta memastikan bahwa / usr / bin / time dipanggil. Ini berarti bahwa dua pernyataan berikut ini sesuai:$ command time -f %e sleep 4
dan$ /usr/bin/time -f %e sleep
coba ini, ia menjalankan perintah sederhana dengan argumen dan menempatkan kali $ real $ user $ sys dan mempertahankan kode keluar.
Itu juga tidak bercabang subshell atau menginjak-injak variabel apa pun kecuali sys pengguna nyata, dan sebaliknya tidak mengganggu jalannya skrip
misalnya
catatan: ini hanya kali perintah sederhana bukan pipa, yang komponennya dijalankan dalam subkulit
Versi ini memungkinkan Anda menentukan $ 1 nama variabel yang harus menerima 3 kali:
misalnya
dan mungkin berguna jika akhirnya dipanggil secara rekursif, untuk menghindari menginjak-injak waktu; tetapi kemudian rus dll harus dinyatakan lokal dalam penggunaannya.
http://blog.sam.liddicott.com/2016/01/timeing-bash-commands.html
sumber