bash プロセスの交換により vipe が誤動作します。

bash プロセスの交換により vipe が誤動作します。

次の簡単なコマンドがあります。

$ echo <(vipe)

編集可能なvimバッファを開き、操作が完了したら、vimバッファの内容を保持するために割り当てられた一時ファイルの名前をエコーし​​ます。

代わりに、vimバッファは特定のキー入力に応答せずに非常に奇妙に動作し、最終的にvimが完全にクラッシュします。

私の仮定のどれが間違っていますか?

ベストアンサー1

まず、端末に表示される内容を見てみましょう。

$ echo <(vim)
/dev/fd/63
$ Vim: Warning: Output is not to a terminal

エディタが終了するのを待たずにすぐにプロンプ​​トが表示されます。プロセスの交換は、コマンドが完了するのを待たずにコマンドとシェルの間にパイプを作成します。パイプの名前は、processが引数で置き換えるコマンドに渡されます。ここでecho名前はすぐに印刷され、返され、その後bashはパイプを閉じます。

標準入力と標準エラーが端末に接続されているVimはまだ実行中ですが、標準出力は接続されていません。したがって、Vimは入力を受け取り、いくつかのエラーメッセージを表示しますが、ほとんどの指示は壊れたパイプである標準出力に進みます。

bashとvimの両方が端末から読み取られます。これにより、キーストロークがどちらの場合でもランダムに送信されます。これは通常発生しません。バックステージコースはい端末での読み取りを無効にする- これを試みるとSIGTTINシグナルを受け取り、シグナルを無視すると呼び出しからreadエラーが返されます。ただし、この場合、vimフォアグラウンドプロセスグループの一部として実行すると、プロセスの置き換えによって新しいプロセスグループが作成されないため、端末から読み取ってキーストロークをキャプチャできます。

ある時点で、Vimはもう耐えられないと判断して終了します。何がそのような決定をすることになったのかわかりません。


プロセスの置き換えは一時ファイルを生成せずにパイプを生成するため、アプローチは意味がありません。ジッシュ一時ファイル()を生成するプロセス置換構造がありますが、=(somecommand)それも機能しません。を実行すると、echo =(vipe </dev/null)印刷時に削除された一時ファイルの名前が印刷されます。

必要な操作を実行するには、一時ファイルの削除を直接処理する必要があります。私はあなたを助けることができるシェル構造がないと思います。mktemp一時ファイルを作成し、通常の方法で編集するには呼び出します。

tmpfile=$(mktemp)
"${VISUAL:-"${EDITOR:-vi}"}" "$tmpfile"
echo "$tmpfile"
rm "$tmpfile"

おすすめ記事