Arti dari '2>> (command)' Redirection di Bash

18

Beberapa waktu yang lalu saya membuat skrip dan menambahkan beberapa logging di sekitarnya, tapi saya lupa bagaimana redirection untuk logging bekerja :-(

Intinya adalah:

#!/bin/bash

LOGFILE=/some/path/mylogfile

(
  # here go my commands which produce some stdout
  # and, if something goes wrong, also some stderr
) 1>>${LOGFILE} 2> >( tee -a ${LOGFILE} >&2 )

Saat saya menjalankan skrip, skrip tidak mencetak apa pun stdout, tetapi hanya mencetak apa yang terjadi stderr. Logfile ${LOGFILE}menangkap stdout dan stderr.

Ketika saya menjalankan skrip dan tidak ada output di terminal saya, maka saya tahu semuanya baik-baik saja. Jika ada output, saya tahu ada yang salah dan saya bisa memeriksa logfile untuk mencari tahu apa masalahnya.

Bagian dari pengalihan yang sekarang membingungkan saya adalah sintaks: 2> >( some command )

Adakah yang bisa menjelaskan apa yang terjadi di sana?

NZD
sumber

Jawaban:

23

>(...)disebut proses substitusi . Itu memungkinkan program "luar" menulis ke program "dalam" seolah-olah itu file.

Dalam hal ini itu menulis stderruntuk tee -a ${LOGFILE} >&2yang akan menambah ke LOGFILEdan kemudian juga menulis semuanya kembali ke stderr.

Operator pengalihan dapat pergi ke salah satu arah untuk substitusi proses, sehingga Anda dapat menulis kepadanya, seperti dalam contoh ini, atau gunakan <(...)untuk membaca darinya, yang merupakan cara yang berguna untuk, misalnya, melakukan whileloop tanpa menjalankannya dalam subkulit diri.

Eric Renouf
sumber
5
Mendapatkannya :-) Jika saya jalankan echo <(date), itu memberi saya nama file diganti: /dev/fd/63. Jika saya jalankan cat <(date), itu memberi saya tanggal, yaitu isi dari file diganti: Fri Nov 18 14:11:09 NZDT 2016.
NZD
@NZD, ya - tapi jangan bayangkan ini file biasa - yang Anda lihat /devadalah nama untuk pipa di antara proses.
Toby Speight
Apakah teknik ini digunakan karena stderr tidak dapat disalurkan (ke tee, dalam kasus ini)?
bli
@ Bli Ya, karena stdout sudah diarahkan ke tempat lain, ini bagi saya sepertinya cara yang paling mudah untuk teestderr dan memisahkannya dari stdout.
Eric Renouf