Mengapa output dari beberapa program Linux tidak menuju ke STDOUT atau STDERR?
Sebenarnya, saya ingin tahu cara menangkap semua hasil program dengan andal, apa pun 'aliran' yang digunakannya. Masalah yang saya miliki adalah bahwa beberapa program tampaknya tidak membiarkan keluarannya ditangkap.
Contohnya adalah perintah 'waktu':
time sleep 1 2>&1 > /dev/null
real 0m1.003s
user 0m0.000s
sys 0m0.000s
atau
time sleep 1 &> /dev/null
real 0m1.003s
user 0m0.000s
sys 0m0.000s
Mengapa saya melihat output dua kali? Saya berharap semuanya bisa disalurkan ke / dev / null .
Aliran keluaran apa yang digunakan waktu, dan bagaimana saya bisa mengirimnya ke file?
Salah satu cara untuk mengatasi masalah adalah dengan membuat skrip Bash , misalnya, yang combine.sh
berisi perintah ini:
$@ 2>&1
Maka output dari 'waktu' dapat ditangkap dengan cara yang benar:
combine.sh time sleep 1 &> /dev/null
(tidak ada output terlihat - benar)
Apakah ada cara untuk mencapai apa yang saya inginkan tanpa menggunakan skrip gabungan terpisah?
2>&1 > /dev/null
berarti "2 sekarang pergi ke tempat 1 pergi (yaitu, terminal, secara default), dan kemudian 1 sekarang pergi ke / dev / null (tetapi 2 masih pergi ke terminal!). digunakan>/dev/null 2>&1
untuk mengatakan "1 pergi sekarang ke / dev / null, lalu 2 pergi ke tempat 1 pergi (yaitu, juga ke / dev / null). Ini masih tidak akan berfungsi di sini karena 'waktu' bawaan tidak akan diarahkan, tetapi secara umum lebih benar (misalnya itu akan berfungsi jika Anda menggunakan / usr / bin / waktu). Pikirkan tentang "2> & 1" sebagai menyalin "arah" 1 ke dalam 2, bukan sebagai 2 menuju 1Jawaban:
Pertanyaan ini dibahas di BashFAQ / 032 . Dalam contoh Anda, Anda akan:
Alasan mengapa
tidak berperilaku seperti yang Anda harapkan karena dengan sintaks itu, Anda akan menginginkan
time
perintahsleep 1 2>/dev/null
(ya, perintahsleep 1
dengan stderr diarahkan ke/dev/null
). Builtintime
bekerja dengan cara yang memungkinkan hal ini terjadi.The
bash
builtin benar-benar dapat melakukan ini karena ... baik, itu builtin a. Perilaku seperti itu tidak mungkin dilakukan dengan perintah eksternal yangtime
biasanya berlokasi di/usr/bin
. Memang:Sekarang, jawaban atas pertanyaan Anda
adalah: ya, outputnya pergi ke stdout atau stderr .
Semoga ini membantu!
sumber
exec 3>/some/file ; ls >&3 ;
)coproc
builtin. Tapi itu tidak berlaku untuktime
builtin.Pertanyaan khusus Anda tentang
time
builtin sudah dijawab, tetapi ada yang beberapa perintah yang tidak menulis baik untukstdout
ataustderr
. Contoh klasik adalah perintah Unixcrypt
.crypt
tanpa argumen mengenkripsi input standarstdin
dan menulisnya ke output standarstdout
. Ini meminta pengguna untuk menggunakan kata sandigetpass()
, yang secara default menampilkan permintaan untuk/dev/tty
./dev/tty
adalah perangkat terminal saat ini. Menulis ke/dev/tty
memiliki efek menulis ke terminal saat ini (jika ada, lihatisatty()
).Alasannya
crypt
tidak bisa menulisstdout
adalah karena ia menulis keluaran terenkripsistdout
. Juga, lebih baik untuk meminta/dev/tty
daripada menulisstderr
sehingga jika pengguna mengalihkanstdout
danstderr
, prompt masih terlihat. (Untuk alasan yang sama,crypt
tidak dapat membaca kata sandistdin
, karena digunakan untuk membaca data yang akan dienkripsi.)sumber
time sleep 1 > /dev/null 2>&1
# mengarahkan ulang output "sleep" do null. Kemudian, "waktu" menulis outputnya sendiri, tanpa pengalihan. Itu seperti "time (sleep 1 > /dev/null 2>&1)
".(time sleep 1) > /dev/null 2>&1
# menjalankan "time sleep 1", lalu mengalihkan outputnya ke nol.[] s
sumber
Masalah dalam kasus Anda adalah bahwa pengalihan berfungsi dengan cara lain. Kau menulis
Ini mengarahkan ulang output standar ke
/dev/null
dan kemudian mengalihkan kesalahan standar ke output standar.Untuk mengarahkan ulang semua hasil yang Anda harus tulis
Kemudian kesalahan standar akan dialihkan ke output standar dan setelah itu semua output standar (berisi kesalahan standar) akan diarahkan ke
/dev/null
.sumber
time
. Lihat jawaban saya untuk beberapa penjelasan.