長すぎます。

長すぎます。

これはvimを狂わせます:

$strace -o >(vim -; stty sane) file.out; stty sane

stty sane処理された代替項目と次のコマンドを入力しましたが、どちらも操作を実行しませんでした。 straceコマンドをvimにパイプするとすぐに、vimは正しく機能しなくなります。 (vimがstdinstraceの出力のみを許可して提供できることを知っていますが、stderrその-oフラグは何をしますか?)助けが必要ですか?

ベストアンサー1

長すぎます。

strace -o '|vim -' file.out

~について-o

-ostdout または stderr とは異なる追加の出力チャネルを提供するために存在します。-o straceコマンドの標準エラーでもある標準エラーには何も印刷されません(file.outあなたの場合)。-oこれを可能にするには、2つのストリームを分離できることをお勧めします。


質問

あなたのアプローチに欠陥があり、あなたが想像していたものと異なることは役に立ちませんstty sane。次のコマンドを繰り返します。

strace -o >(vim -; stty sane) file.out; stty sane

これには2つの一般的な問題があります。

  1. ジョブ制御が有効になると概念が表示されます。フォアグラウンドプロセスグループ。いつでも端末は前景のグループを認識します。フォアグラウンドプロセスグループに属さないプロセスは、正式にバックグラウンドにあります。

バックグラウンドプロセスは制御端末からデータを読み取ることができない。SIGTTINしようとするとデータを受信します。このシグナルは、プロセスがそれを無視したり別の方法で処理しない限り、それをブロックします。

バックグラウンド・プロセスは制御端末に書き込むことができますが、試みてアクティブにstty tostopなると、プロセスがシグナルSIGTTOUを無視したり、別の方法で処理しない限り、シグナルを受け取ります。停止しない場合、tostopプロセスは信号にもかかわらず、端末に書き込むことができます。

上記のメカニズムは、バックグラウンドプロセスが端末から入力を盗むのを防ぎますが、端末に接続されたままになり、フォアグラウンドにインポートして操作できるようにします。それから端末から読みます。これは、プロセスを開始する端末に便利です。他の端末との可能な相互作用は、前景または背景にあるものとは何の関係もなく、他の端末はとにかく「外部」です。したがって、プロセスは十分な権限を持っている限り、制御端末ではなく端末から読み書きできます。 。

あなたの場合、最初はフォアグラウンドプロセスグループがシェルに関連付けられています。と(外部);最後に、再びシェルに関連するstraceものsttyです>()

Bash内のプロセスは>()プロセスに割り当てられます。>()これは、(外部)プロセスが完了し、シェルのプロセスグループがフォアグラウンドにインポートされたvim後にのみ端末からデータを読み取ることができることを意味します。これは2番目の問題を引き起こします。stracestty>()

  1. vim最終的に端末から読み取れるようになると、シェルも読み取ろうとします。次の2つを比較します。
  • strace -o >(vim -) true

    カーソルを移動します。一部の入力はシェルに移動しvim、一部の入力はシェルに移動します。彼らはすべてフロントデスクにあります。

  • strace -o >(vim -) true; sleep 1000

    カーソルを動かしてみてください。今はsleep前景にあるので違います。 +sleepで終了すると動作が変わります。CtrlC

いずれの場合でも、vim他のコンソールからシャットダウンして回復できます(killall vim他のコンソールがあり、vimそれを維持したい場合を除く)。

これがあなたが観察する狂気です。犯人はまたはの範囲外ですstty saneresettput reset


面倒なこと

  1. 次のコマンドは別の狂気を生成します。

     <<<"foo" tee >(vim -)
     <<<"foo" tee > >(vim -)
    

最初のケースは>()メインシェルによって処理され、vimシェルのプロセスグループに配置されます。終了すると、端末からデータを読み取ることができますtee(シェルは干渉しますが)strace

2番目のケースは>()処理シェルによって処理されます>。 (exec to)になるサブシェルですtee。実際にはvimプロセスグループに配置されますtee。フォアグラウンドの1つのtee端末からデータを読み取ることができます。

ほぼ即座に終了するので、tee最初の項目はvim端末でほぼすぐに読み取ることができますが、2番目の項目はvimほとんどすぐに読み取ることができません。

  1. 私のテストでは、>(vim -)Zshは処理以外のプロセスグループにあり、絶対vimフォアグラウンドにはないことがわかりました。他に違いがあるようですが、詳細は取り上げません。>()vim

一般的なソリューション(に依存しないstrace

  • ジョブ制御が無効になると(set +mサブシェルでコードを使用または実行して)、すべての新しいプロセスは端末が前景として処理するグループに属します。シェルへの戻りを遅らせると、シェルは端末からデータを読み取ることを妨げません。この試み:

      (strace -o >(vim -) file.out; sleep 99999)
    

終了後にCtrl+終了を使用してくださいC。この組み合わせをクリックすると、端末も同じように構成されているため影響を受けません。sleepvimvimsleepvimstty -isig

このソリューションはあまりエレガントではありません。ジョブ制御を無効にし、シェルが入力を読み取らないようにすることがどのように影響するかを示すため、これをここに入れました。

  • または、vim前景から始めて維持する必要があります。使用しないでください>(vim -)vim …またはを使用してください… | vim -

最も簡単な方法は、通常のファイルを作成し(あなたの場合strace -o somefile file.out)、後で開くことです(vim somefile)。


ソリューションは具体的にターゲットを指定します。strace

ファイルの生成を避けて使用するか、可能なvim <(strace …)解決策です。私はあなたが十分にスマートであれば(そしてあなたは持っていますか?)、元のstdoutとマージすることなくファイル記述子を操作してstdoutにパイプすることができるとstrace … | vim -思います。/proc-o

正しいことただし、strace提供されている以下を使用してください-o

-o filename
--output=filename

filenamestderrの代わりにファイルにトレース出力を書き込みます。 [… ]引数|がまたはで始まる場合、引数!の残りの部分はコマンドとして処理され、すべての出力はそのコマンドにパイプされます。これにより、実行されたプログラムのリダイレクトに影響を与えることなく、デバッグ出力をプログラムに簡単にパイプできます。 [… ]

源泉、強調内)

あなたのコマンドは次のとおりです

strace -o '|vim -' file.out

引用または|エスケープする必要があります。それ以外の場合、シェルはパイプを構築しようとします。別のオプションはいくつかのシェル!です。保護されなければならないしかも。

strace走ってshsh上記vimの問題が修正されました。それぞれ:

  1. これら3つのプロセスは同じプロセスグループに属します。straceフロントにいる場合はフロントにありますvim

  2. 対話型(外部)シェルは、終了後にのみ端末から読み取りを試みますstraceshvim

おすすめ記事