システム情報:
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)
私が作成した簡単な例を詳しく知りたい場合は、一番下の「例」までスクロールしてください。
注:私は大したzshユーザーではありません。
どちらも変数コマンドを実行する方法に注意してください$(__fzfcmd)。__fzfcmdデフォルトでfzfはstdoutに出力し、パラメーター置換fzfは出力から得られたコマンド()を実行するだけです。
間の一つの違いbashとzshスクリプトがあることbashつの更なるパイプの出力は$(__fzfcmd)なく、zsh単に配列の内部に取り込みます。私の推測では、入力できない場所zshの出力をさらにパイプfzfするfzfと、パイプされたプロセスがfzfstdinを取得できないという問題が発生したためです。あなたの唯一の選択は、^Zまたは^Cです。^Cなんらかの理由でプロセスの背景になっているようです。または、多分彼らはそれを実行zle vi-fetch-historyすることができるように配列でそれを望んだだけです。bashバージョンは、との結合キーにいくつかの魔法を行います"\e^": history-expand-line
今fzfは重要ではありません。ttyこの問題を発生させるには、パラメータ置換によって呼び出されるに出力するプログラムが必要なだけのようです。そこで、いくつかの簡単な例を示します。
でttyこの問題を引き起こす可能性のあるに出力される他のいくつかのコマンドを次に示しますzsh。
- vipe(パイプの途中でエディターを実行)
'vim -'(vimをstdinから読み取ります。vipeと同様ですが、stdoutに出力されません)
以下の例で、個別にインストールしたくない場合は、vipeをすべてで置き換えてvim -ください。ただ、それは覚えているvim -ような標準出力に出力し、エディタの内容をしませんvipeありません。
例:
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
今、私はほとんど、なぜ思ったんだけど2)ために問題を抱えているzshではないためbash、その理由4)と5)するために問題を修正しますzsh。
zshこの問題が発生するための要件は、私がタイトルに入力したとおりのように見えます。
- 入力パイプ
tty出力を持つ変数/パラメーター置換によって実行されるコマンド- 出力パイプ
更新
zshこの問題を引き起こさない別の回避策を追加しました5)。に似て4)いますが、にstdout直接リダイレクトする代わりに、プロセス置換stinをstdin使用してリダイレクトするファイルにリダイレクトします。
when either a computer program or system ceases to respond to inputs
(echo | $(echo vipe) | cat)
psわかるように、これらのいずれの場合も、シェルはフリーズまたはスタックしていません。彼らは単に通常の方法で子プロセスを待っています。そして、それらの子プロセスが一時停止または終了すると、通常の方法で入力を求めるプロンプトにループバックします。質問のタイトルと本文に暗黙の誤った前提が含まれています。「なぜシェルがフリーズするのですか?」シェルが最初に実際にフリーズしていない場合、答えのないロードされた質問です。この暗黙の誤った前提を取り除くためのより良い質問があるでしょう。