
システムメッセージ:
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
。
私が見ています。fzf
キーバインディングbash
そしてzsh
。
それらすべてがどのように変数コマンドを実行するかに注意してください$(__fzfcmd)
。__fzfcmd
デフォルトでは、出力はfzf
stdoutで構成され、引数置換はfzf
結果を出力するcommand()のみを実行します。
bash
スクリプトとスクリプトの1つの違いzsh
は、スクリプトがbash
出力をさらにパイプする$(__fzfcmd)
が、zsh
それを配列としてキャプチャすることです。私の考えでは、zsh
入力できない追加のパイプ出力とパイプするプロセスが標準入力を取得できないときに問題が発生するためです。唯一のオプションはまたはです。なぜかバックグラウンドでプロセスが処理されているようです。あるいは、単に配列に入れて使用することもできます。fzf
fzf
fzf
^Z
^C
^C
zle vi-fetch-history
それにかかって。このbash
バージョンでは、キーバインディングに関するいくつかのタスクを実行します。"\e^": history-expand-line
今は重要ではありませんfzf
。tty
この問題を引き起こすには、パラメータ置換によって呼び出されたプログラムへの出力のみが必要です。だからもう少し簡単な例を見てみましょう。
tty
この問題を引き起こす可能性がある他のコマンドの出力は次のとおりですzsh
。
- 蛇(パイプラインの途中でエディタを実行します)
'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
答え1
あなたの問題は、あなたの拡張機能を誤って引用したものとして要約されます。
から引用zsh:14 拡張
$(...)
括弧で囲まれ、ドル記号(例:)が前に付くか、アクセント文字(例: '')で引用されたコマンドは...
標準出力を置き換え、末尾の改行文字を削除します。代替項目を二重引用符で囲まない場合は、IFSパラメーターを使用して出力を単語に分割します。代替品は$(cat foo)
同じですが、より速い代替品に置き換えることができます$(<foo)
。どちらの場合も、GLOB_SUBSTオプションが設定されている場合、出力はファイル名の生成に従います。
質問の例#2は、次の理由で無限のNULLエコーを生成します。
代替項目を二重引用符で囲まない場合は、IFSパラメーターを使用して出力を単語に分割します。
つまり、echo
デフォルトの区切り文字がSPACEであるため、シェルは無期限に待機するため、echoは完了しません。 TLDP:内部変数を参照してください。。これにより、cat
コマンドのハングパイプが残ります。
直感的に、私は出力リダイレクトのために4と5が動作すると信じています。