tty 出力で可変コマンドパイプ stdin と stdout を使用すると、zsh は端末に入力できません。

tty 出力で可変コマンドパイプ stdin と stdout を使用すると、zsh は端末に入力できません。

システムメッセージ:

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デフォルトでは、出力はfzfstdoutで構成され、引数置換はfzf結果を出力するcommand()のみを実行します。

bashスクリプトとスクリプトの1つの違いzshは、スクリプトがbash出力をさらにパイプする$(__fzfcmd)が、zshそれを配列としてキャプチャすることです。私の考えでは、zsh入力できない追加のパイプ出力とパイプするプロセスが標準入力を取得できないときに問題が発生するためです。唯一のオプションはまたはです。なぜかバックグラウンドでプロセスが処理されているようです。あるいは、単に配列に入れて使用することもできます。fzffzffzf^Z^C^Czle vi-fetch-historyそれにかかって。このbashバージョンでは、キーバインディングに関するいくつかのタスクを実行します。"\e^": history-expand-line

今は重要ではありませんfzfttyこの問題を引き起こすには、パラメータ置換によって呼び出されたプログラムへの出力のみが必要です。だからもう少し簡単な例を見てみましょう。

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)ではなく、プロセス置換を使用するようにリダイレクトするファイルにリダイレクトします。stdoutstinstdin

ベストアンサー1

あなたの問題は、あなたの拡張機能を誤って引用したものとして要約されます。

から引用zsh:14 拡張

$(...)括弧で囲まれ、ドル記号(例:)が前に付くか、アクセント文字(例: '')で引用されたコマンドは ...標準出力を置き換え、末尾の改行文字を削除します。代替項目を二重引用符で囲まない場合は、IFSパラメーターを使用して出力を単語に分割します。代替品は$(cat foo)同じですが、より速い代替品に置き換えることができます$(<foo)。どちらの場合も、GLOB_SUBSTオプションが設定されている場合、出力はファイル名の生成に従います。

質問の例#2は、次の理由で無限のNULLエコーを生成します。

代替項目を二重引用符で囲まない場合は、IFSパラメーターを使用して出力を単語に分割します。

つまり、echoデフォルトの区切り文字がSPACEであるため、シェルは無期限に待機するため、echoは完了しません。 TLDP:内部変数を参照してください。。これにより、catコマンドのハングパイプが残ります。

直感的に、私は出力リダイレクトのために4と5が動作すると信じています。

おすすめ記事