Pengalihan I / O zsh: pengalihan dan kemudian pemipaan; apa yang sedang terjadi?

8

Adakah yang bisa menjelaskan apa yang terjadi dalam perintah ini:

echo foo >&2 | grep foo

Zsh (5.0.2) mencetak foodua kali. Satu tampaknya stdout dan satu ke stderr, karena menjalankan perintah ini:

{ echo foo >&2 | grep foo } >/dev/null

dan:

{ echo foo >&2 | grep foo } 2>/dev/null

keduanya hanya mencetak foosekali.

Zorawar
sumber

Jawaban:

5

Itulah efek MULTIOS .

echo foo >&2 | grep foo

akan menulis fooke stderr dan juga pipa fooke grep. Karena stderr default ke terminal, Anda akan melihat dua foobaris, satu dari echo, satu dari grephasilnya.

{ echo foo >&2 | grep foo } >/dev/null

Di sini, Anda melihat satu baris karena stdout dialihkan ke /dev/null, Anda hanya melihat foogaris dari echo.

{ echo foo >&2 | grep foo } 2>/dev/null

Di sini, Anda melihat satu baris karena stderr dialihkan ke /dev/null, Anda hanya melihat foogaris dari grep.

Anda dapat dengan mudah melihat perbedaan di terminal dengan warna garis keluaran. grepakan menyorot pola yang cocok (atau Anda bisa memaksanya dengan menggunakan --color=always).


MULTIOSdiaktifkan secara default dengan nomultiosopsi tidak disetel:

$ unsetopt | grep nomultios
nomultios

Untuk menonaktifkannya, cukup atur nomultiosopsi:

$ setopt nomultios
cuonglm
sumber
Ah, saya tidak tahu zsh bisa melakukan itu! Saya (pada dasarnya) mengerti pengalihan, saya ingin tahu mengapa perintah itu tidak setara dengan {echo foo >&2} | grep foo, jika Anda melihat apa yang saya coba katakan. Saya pikir perintah yang saya tanyakan di atas akan mengarahkan stdout ke stderr dan kemudian mengirim stdout kosong ke grep.
Zorawar
@Zorawar: Pertanyaan itu tidak dibahas di pos Anda, jadi saya akan jawab di sini. Di {echo foo >&2} | grep foo, {echo foo >&2}dianggap sebagai perintah, dan itu berjalan dalam subkulit. Anda dapat berpikir seperti A | grep foomana Aadalah {echo foo >&2}. Dalam hal ini, >&2dan |dipisahkan, MULTIOStidak berpengaruh di sini.
cuonglm
@Zorawar Kasus ini adalah mengapa saya akhirnya mematikan multios. Ini adalah ide yang lucu, tetapi dalam praktiknya saya sering merasa menjengkelkan dan jarang berguna.
Gilles 'SANGAT berhenti menjadi jahat'
@cuonglm, saya punya pertanyaan lain yang ditanyakan di sini tetapi tidak mendapatkan jawaban. Jika Anda mengetahuinya dan juga punya waktu, bisakah Anda membantu?
Liu Sha