Hal pertama yang perlu diperhatikan adalah bahwa ada beberapa cara tergantung pada tujuan dan cangkang anda, oleh karena itu ini membutuhkan sedikit pemahaman tentang berbagai aspek. Selain itu, perintah tertentu seperti time
dan strace
tulis output ke stderr secara default, dan mungkin atau mungkin tidak menyediakan metode pengalihan khusus untuk perintah itu
Teori dasar di balik pengalihan adalah bahwa proses yang dihasilkan oleh shell (dengan asumsi itu adalah perintah eksternal dan bukan shell built-in) dibuat melalui fork()
dan execve()
syscall, dan sebelum itu terjadi syscall lain dup2()
melakukan pengalihan yang diperlukan sebelum execve()
terjadi. Dalam hal ini, pengalihan diwarisi dari shell induk. The m&>n
dan m>n.txt
menginformasikan shell tentang cara melakukan open()
dan dup2()
syscall (lihat juga Cara kerja pengalihan masukan, Apa perbedaan antara pengalihan dan pipa, dan Apa arti & amp; sebenarnya dalam pengalihan keluaran )
Pengalihan Shell
Paling khas, adalah melalui 2>
di Kerang seperti Bourne, seperti dash
(yang symlinked ke /bin/sh
) dan bash
; pertama adalah shell default dan POSIX-compliant dan yang lainnya adalah apa yang sebagian besar pengguna gunakan untuk sesi interaktif. Mereka berbeda dalam sintaks dan fitur, tetapi untungnya bagi kami pengalihan aliran kesalahan berfungsi sama (kecuali &>
non standar satu). Dalam kasus csh dan turunannya, pengalihan stderr tidak cukup bekerja di sana.
Mari kita kembali ke 2>
bagian. Dua hal penting untuk diperhatikan: >
berarti operator pengalihan, di mana kita membuka file dan 2
integer adalah singkatan dari stderr file descriptor; sebenarnya ini persis bagaimana standar POSIX untuk bahasa shell mendefinisikan redirection di bagian 2.7:
[n]redir-op word
Untuk sederhana >
pengalihan, yang 1
integer tersirat untuk stdout
, yaitu. echo Hello World > /dev/null
sama saja dengan echo Hello World 1>/dev/null
. Perhatikan, bahwa operator integer atau redirection tidak dapat dikutip, jika tidak shell tidak mengenalinya, dan sebaliknya memperlakukan sebagai string teks literal. Sedangkan untuk spasi, penting bahwa integer berada tepat di sebelah operator pengalihan, tetapi file dapat berada di sebelah operator pengalihan atau tidak, yaitu. command 2>/dev/null
dan command 2> /dev/null
akan bekerja dengan baik.
Sintaks yang agak disederhanakan untuk perintah tipikal di shell adalah
command [arg1] [arg2] 2> /dev/null
Kuncinya di sini adalah bahwa pengalihan dapat muncul di mana saja. Itu keduanya 2> command [arg1]
dan command 2> [arg1]
valid. Perhatikan bahwa untuk bash
shell, ada ada ada &>
cara untuk mengalihkan aliran stdout dan stderr secara bersamaan, tetapi sekali lagi - ini spesifik bash dan jika Anda berjuang untuk portabilitas skrip, itu mungkin tidak berfungsi. Lihat juga Ubuntu Wiki dan >>Apa perbedaan antara & amp; dan 2 & amp; 1.
Catatan: The >
operator pengalihan truncates file dan menimpa itu, jika file tersebut ada. The 2>>
dapat digunakan untuk menambahkan stderr
untuk mengajukan.
Jika Anda mungkin memperhatikan, >
dimaksudkan untuk satu perintah tunggal. Untuk skrip, kita dapat mengarahkan aliran stderr dari seluruh skrip dari luar seperti di myscript.sh 2> /dev/null
atau kita bisa menggunakan exec built-in. Exec built-in memiliki kekuatan untuk memutar ulang aliran untuk seluruh sesi shell, sehingga untuk berbicara, baik secara interaktif atau melalui skrip. Sesuatu seperti
#!/bin/shexec 2> ./my_log_file.txtstat /etc/non_existing_file
Dalam contoh ini, file log harus menunjukkan stat: cannot stat '/etc/non_existing_file': No such file or directory
.
Cara lain adalah melalui fungsi. As Cinderella dicatat dalam jawabannya, kita dapat menulis deklarasi fungsi dengan pengalihan yang sudah terpasang, yaitu
some_function(){ command1 command2} 2> my_log_file.txt
Perintah menulis ke stderr secara eksklusif
Perintah seperti time
dan strace
tulis outputnya ke stderr secara default. Dalam kasus time
perintah, satu-satunya alternatif adalah untuk mengarahkan output dari seluruh perintah , yaitu
time echo foo 2>&1 > file.txt
atau, daftar Sinkron atau subkulit dapat dialihkan jika Anda ingin memisahkan output ( seperti yang ditunjukkan pada artikel terkait ):
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
Perintah lain, seperti strace
atau dialog
menyediakan sarana untuk mengarahkan stderr. strace
memiliki -o <filename.txt>
opsi yang memungkinkan menentukan nama file di mana output harus ditulis. Ada juga pilihan untuk menulis textfile untuk setiap subproses yang strace
melihat. The dialog
perintah menulis antarmuka pengguna teks ke stdout tetapi output ke stderr, jadi untuk Simpan outputnya ke variabel (karena var=$(...)
dan pipeline hanya menerima stderr) kita perlu menukar deskriptor file
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
tapi selain itu, ada --output-fd
bendera, yang juga bisa kita manfaatkan. Ada juga metode bernama pipa. Saya sarankan membaca posting terkait tentang dialog
perintah untuk deskripsi menyeluruh tentang apa yang terjadi.