バインディングを一覧表示すると、Bashプロセスの交換が中断されます。

バインディングを一覧表示すると、Bashプロセスの交換が中断されます。

要約:

cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs') # freezes

# I can't use this because I need to pipe the output of the bind
cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs' &) # doesn't freeze

# I can use this. This won't work for comm below since it takes two file inputs.
cat < <(INPUTRC=/dev/null bash -c 'bind -pm emacs') # doesn't freeze

# I can use this.
cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs') & fg # doesn't freeze

# I can use this. This is my current solution
cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs') | cat # doesn't freeze

何が停止するのか、そしてバックグラウンドで問題を解決できるのはなぜですか?これ何が起こったと言いましたEOF。だから待ってくださいstdin。注射する方法はありますかEOF?なぜ一つが欠けたのですかEOF


これがバグなのか、それとも私が何か間違っているのかわかりません。

macOSでbash-4.4.12(1)-releaseを使用していますが、およびを使用してテストした結果、gnu-grep同じgnu-sort結果が得られました。

追加のファイルを生成する必要がないように、プロセス置換を使用してbashのデフォルトバインディングを比較したいと思います。

これがEmacsの基本バインディングを取得する方法です。私は空の状態でbashコマンドを実行しますINPUTRC。これは、後で使用するバインディングとこれらのバインディングとを比較するためにgrep不要なバインディングを削除することです。ここでこのコマンドを受けました。sortemacsvicommここ

INPUTRC=/dev/null bash -c 'bind -pm emacs' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort

今回もvi-insertデフォルトのバインディングを取得する方法は次のとおりです。ただ交換しemacsてくださいvi-insert

INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
sort

今、これら2つのコマンドを比較したいcommので、これら2つのコマンドをプロセス全体でラップして実行しますcomm

comm \
  <(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) \
  <(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort)

出力:

bash: line 0: bind: warning: line editing not enabled
bash: line 0: bind: warning: line editing not enabled
... (empty. I have to press CTRL+C to exit)

今は簡単に保つためにこれも停止します。

cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs')

だから私が見つけたこれ状況が役に立つと言って&実際にそうです。

cat <(INPUTRC=/dev/null bash -c 'bind -pm emacs' &) # works, has output, no freeze

これで、この知識を元のコマンドに適用しようとしましたが、パイプがあるためそれを行うことはできません。

...'bind -pm emacs' &|... # doesn't work
...'bind -pm emacs' |&... # doesn't work, this is for redirecting stderr to stdout

その後、すべてを完全にコンテキスト化しようとします。&長いコマンドの最後に追加されます。fgそれでは、1行のコマンドとして残してください。これは効果があります

comm \
  <(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) \
  <(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) & fg

Pipe to Catも修正しました。

comm \
  <(INPUTRC=/dev/null bash -c 'bind -pm emacs' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) \
  <(INPUTRC=/dev/null bash -c 'bind -pm vi-insert' |
    LC_ALL='C' grep -vE '^#|: (do-lowercase-version|self-insert)$' |
    sort) | cat

私はフリーズコマンドを使用して端末を閉じようとしたとき、これらのプロセスはまだ実行中であることがわかりました。したがって、CTRL + Cはこれらのコマンドを停止しません。 ビデオ

何が起こっているのか知っている人はいますか?

関連情報