Sistem Informasi:
macOS Sierra 10.12.6
zsh 5.4.2 (x86_64-apple-darwin16.7.0)
GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin16.3.0)
Gulir ke CONTOH di bagian bawah jika Anda hanya ingin menggali contoh sederhana yang saya buat.
CATATAN: Saya bukan zshpengguna besar .
Saya mencari di fzfkeybindings untuk bashdan zsh.
Perhatikan bagaimana keduanya menjalankan perintah variabel $(__fzfcmd). __fzfcmdsecara default output fzfke stdout dan substitusi parameter hanya menjalankan perintah ( fzf) yang dihasilkan dari output.
Satu perbedaan antara skrip bashdan zshadalah skrip yang bashlebih lanjut mem-pipe output $(__fzfcmd)tetapi zshhanya menangkapnya di dalam array. Dugaan saya adalah karena masalah zshketika Anda lebih lanjut mem-pipkan output di fzfmana Anda tidak dapat input ke fzfdan proses piped by fzftidak mendapatkan stdin. Satu-satunya pilihan Anda adalah ^Zatau ^C. ^CSepertinya latar belakang proses karena beberapa alasan. Atau mungkin mereka hanya ingin dalam array sehingga mereka bisa bisa berjalan zle vi-fetch-historydi atasnya . The bashVersi melakukan sihir di kunci mengikat dengan"\e^": history-expand-line
Sekarang fzftidak penting. Sepertinya Anda hanya perlu program yang menampilkan ke ttyuntuk dipanggil oleh substitusi parameter untuk menyebabkan masalah ini. Jadi saya akan menunjukkan beberapa contoh sederhana.
Berikut adalah beberapa perintah lain yang menghasilkan ttyyang dapat menyebabkan masalah ini di zsh:
- vipe (jalankan editor di tengah-tengah pipa)
'vim -'(membuat vim dibaca dari stdin. mirip dengan vipe tetapi tidak akan menampilkan ke stdout)
Dalam contoh di bawah ini, ganti setiap kejadian vipedengan vim -jika Anda tidak ingin melakukan pemasangan terpisah. Ingat saja bahwa vim -tidak akan menampilkan konten editor ke stdout seperti vipehalnya.
CONTOH:
1) echo 1 | vipe | cat # works in both bash and zsh
2) echo 1 | $(echo vipe) | cat # works in bash only. zsh problem with no output until I hit `^C`:
^C
zsh: done echo 1 |
zsh: suspended (tty output) $(echo vipe) |
zsh: interrupt cat
# seems like the process is backgrounded. I can still see it in jobs command
3) cat <(echo 1 | $(echo vipe)) # zsh and bash has the problem. I'm guessing because
# the file isn't finished writing and cat is
# blocking vipe's tty output
# both their `^C` output is just:
^C # nothing special, as expected
4) cat < <(echo 1 | $(echo vipe)) # works in both bash and zsh
5) echo 1 | $(echo vipe) > >(cat) # works in both bash and zsh
# The following don't have and input pipe to vipe.
# Type something then send EOF with ^D
6) vipe | cat # works for both
7) $(echo vipe) | cat # works for both
Sekarang, saya sebagian besar bertanya-tanya mengapa 2)ada masalah untuk zshtetapi tidak untuk bashdan mengapa 4)dan 5)memperbaiki masalah untuk zsh.
Persyaratan untuk zshmemiliki masalah ini tampaknya persis seperti yang saya cantumkan pada judul:
- pipa input
- perintah dijalankan oleh substitusi variabel / parameter yang memiliki
ttyoutput - pipa keluaran
MEMPERBARUI
Saya menambahkan solusi lain yang tidak menyebabkan zshmasalah ini 5),. Ini mirip dengan 4)tetapi alih-alih mengarahkan stdoutlangsung ke stin, saya mengarahkan kembali ke file yang mengarahkan kembali stdinmenggunakan proses substitusi.
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
psAnda, dalam semua kasus ini tidak ada cangkang yang beku atau macet. Mereka hanya menunggu proses anak dengan cara normal; dan mereka memang akan kembali ke meminta input dengan cara normal setelah proses anak ditangguhkan atau dihentikan. Judul dan badan pertanyaan Anda termasuk premis palsu implisit. "Mengapa cangkangku membeku?" adalah pertanyaan yang tidak dapat dijawab ketika shell Anda tidak benar - benar membeku. Anda akan memiliki pertanyaan yang lebih baik untuk menghapus premis palsu implisit ini.