Saya memiliki file bash yang saya perlukan untuk mengarahkan semua output ke satu file, debug log juga ke terminal. Saya perlu mengarahkan ulang stdout dan stderr ke debug dan mencatatnya untuk semua perintah dalam skrip.
Saya tidak ingin menambahkan 2>&1 | tee -a $DEBUG
untuk setiap perintah dalam file. Saya bisa hidup dengan | tee -a $DEBUG
.
Saya ingat ada cara untuk melakukannya dengan sesuatu seperti exec 2>&1
.
Saat ini saya menggunakan sesuatu seperti berikut:
#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG
tetapi tidak berhasil. Adakah yang punya solusi / bisa menjelaskan penyebabnya?
bash
io-redirection
Avi
sumber
sumber
|&
berfungsi sebagai jalan pintas2>&1 |
, setidaknya sedikit lebih nyaman.Jawaban:
Adapun solusi untuk mengarahkan banyak perintah sekaligus:
Mengapa solusi asli Anda tidak berfungsi: exec 2> & 1 akan mengarahkan output kesalahan standar ke output standar shell Anda, yang, jika Anda menjalankan skrip Anda dari konsol, akan menjadi konsol Anda. pengalihan pipa pada perintah hanya akan mengarahkan output standar dari perintah.
Pada sudut pandang
somecommand
, output standarnya masuk ke pipa yang terhubungtee
dan kesalahan standar masuk ke file / pseudofile yang sama dengan kesalahan standar shell, yang Anda arahkan ke output standar shell, yang akan menjadi konsol jika Anda menjalankan program Anda dari konsol.Satu-satunya cara yang benar untuk menjelaskannya adalah dengan melihat apa yang sebenarnya terjadi:
Lingkungan asli shell Anda mungkin terlihat seperti ini jika Anda menjalankannya dari terminal:
Setelah Anda mengarahkan kesalahan standar ke output standar (
exec 2>&1
), Anda ... pada dasarnya tidak mengubah apa pun. Tetapi jika Anda mengarahkan output skrip standar ke file, Anda akan berakhir dengan lingkungan seperti ini:Kemudian mengarahkan kesalahan standar shell ke output standar akan berakhir seperti ini:
Menjalankan perintah akan mewarisi lingkungan ini. Jika Anda menjalankan perintah dan mengirimkannya ke tee, lingkungan perintahnya adalah:
Jadi kesalahan standar perintah Anda masih mencakup apa yang digunakan shell sebagai kesalahan standarnya.
Anda benar-benar dapat melihat lingkungan perintah dengan melihat
/proc/[pid]/fd
: gunakanls -l
juga untuk membuat daftar konten tautan simbolik. The0
File sini adalah standar input,1
output standar dan2
standar error. Jika perintah membuka lebih banyak file (dan sebagian besar program melakukannya), Anda juga akan melihatnya. Suatu program juga dapat memilih untuk mengalihkan atau menutup input / output standar dan menggunakan kembali0
,1
dan2
.sumber
Anda dapat menggunakan exec seperti ini di bagian atas skrip Anda:
Sebagai contoh:
Memberi saya output ke file
$HOME/somefile.log
dan ke terminal seperti ini:sumber
/bin/sh
skrip (banyak orang keliru menggunakan sintaks bash dalam/bin/sh
skrip)./dev/fd/62: Operation not supported
petunjuk?myscript
dan saya jalankan./myscript > /dev/null
, saya masih harus melihatbye
yang berasalecho bye >&2
.Tulis stderr dan stdout ke file, tampilkan stderr di layar (on stdout)
Berguna untuk crons, sehingga Anda dapat menerima kesalahan (dan hanya kesalahan) melalui surat
sumber