
これはvimを狂わせます:
$strace -o >(vim -; stty sane) file.out; stty sane
stty sane
処理された代替項目と次のコマンドを入力しましたが、どちらも操作を実行しませんでした。 straceコマンドをvimにパイプするとすぐに、vimは正しく機能しなくなります。 (vimがstdin
straceの出力のみを許可して提供できることを知っていますが、stderr
その-o
フラグは何をしますか?)助けが必要ですか?
答え1
長すぎます。
strace -o '|vim -' file.out
~について-o
-o
stdout または stderr とは異なる追加の出力チャネルを提供するために存在します。-o
strace
コマンドの標準エラーでもある標準エラーには何も印刷されません(file.out
あなたの場合)。-o
これを可能にするには、2つのストリームを分離できることをお勧めします。
質問
あなたのアプローチに欠陥があり、あなたが想像していたものと異なることは役に立ちませんstty sane
。次のコマンドを繰り返します。
strace -o >(vim -; stty sane) file.out; stty sane
これには2つの一般的な問題があります。
- ジョブ制御が有効になると概念が表示されます。フォアグラウンドプロセスグループ。いつでも端末は前景のグループを認識します。フォアグラウンドプロセスグループに属さないプロセスは、正式にバックグラウンドにあります。
バックグラウンドプロセスは制御端末からデータを読み取ることができない。SIGTTIN
しようとするとデータを受信します。このシグナルは、プロセスがそれを無視したり別の方法で処理しない限り、それをブロックします。
バックグラウンド・プロセスは制御端末に書き込むことができますが、試みてアクティブにstty tostop
なると、プロセスがシグナルSIGTTOU
を無視したり、別の方法で処理しない限り、シグナルを受け取ります。停止しない場合、tostop
プロセスは信号にもかかわらず、端末に書き込むことができます。
上記のメカニズムは、バックグラウンドプロセスが端末から入力を盗むのを防ぎますが、端末に接続されたままになり、フォアグラウンドにインポートして操作できるようにします。それから端末から読みます。これは、プロセスを開始する端末に便利です。他の端末との可能な相互作用は、前景または背景にあるものとは何の関係もなく、他の端末はとにかく「外部」です。したがって、プロセスは十分な権限を持っている限り、制御端末ではなく端末から読み書きできます。 。
あなたの場合、最初はフォアグラウンドプロセスグループがシェルに関連付けられています。と(外部);最後に、再びシェルに関連するstrace
ものstty
です>()
。
Bash内のプロセスは>()
プロセスに割り当てられます。>()
これは、(外部)プロセスが完了し、シェルのプロセスグループがフォアグラウンドにインポートされたvim
後にのみ端末からデータを読み取ることができることを意味します。これは2番目の問題を引き起こします。strace
stty
>()
vim
最終的に端末から読み取れるようになると、シェルも読み取ろうとします。次の2つを比較します。
strace -o >(vim -) true
カーソルを移動します。一部の入力はシェルに移動し
vim
、一部の入力はシェルに移動します。彼らはすべてフロントデスクにあります。strace -o >(vim -) true; sleep 1000
カーソルを動かしてみてください。今は
sleep
前景にあるので違います。 +sleep
で終了すると動作が変わります。CtrlC
いずれの場合でも、vim
他のコンソールからシャットダウンして回復できます(killall vim
他のコンソールがあり、vim
それを維持したい場合を除く)。
これがあなたが観察する狂気です。犯人はまたはの範囲外ですstty sane
。reset
tput reset
面倒なこと
次のコマンドは別の狂気を生成します。
<<<"foo" tee >(vim -) <<<"foo" tee > >(vim -)
最初のケースは>()
メインシェルによって処理され、vim
シェルのプロセスグループに配置されます。終了すると、端末からデータを読み取ることができますtee
(シェルは干渉しますが)strace
。
2番目のケースは>()
処理シェルによって処理されます>
。 (exec to)になるサブシェルですtee
。実際にはvim
プロセスグループに配置されますtee
。フォアグラウンドの1つのtee
端末からデータを読み取ることができます。
ほぼ即座に終了するので、tee
最初の項目はvim
端末でほぼすぐに読み取ることができますが、2番目の項目はvim
ほとんどすぐに読み取ることができません。
- 私のテストでは、
>(vim -)
Zshは処理以外のプロセスグループにあり、絶対vim
フォアグラウンドにはないことがわかりました。他に違いがあるようですが、詳細は取り上げません。>()
vim
一般的なソリューション(に依存しないstrace
)
ジョブ制御が無効になると(
set +m
サブシェルでコードを使用または実行して)、すべての新しいプロセスは端末が前景として処理するグループに属します。シェルへの戻りを遅らせると、シェルは端末からデータを読み取ることを妨げません。この試み:(strace -o >(vim -) file.out; sleep 99999)
終了後にCtrl+終了を使用してくださいC。この組み合わせをクリックすると、端末も同じように構成されているため影響を受けません。sleep
vim
vim
sleep
vim
stty -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
filename
stderrの代わりにファイルにトレース出力を書き込みます。 [… ]引数|
がまたはで始まる場合、引数!
の残りの部分はコマンドとして処理され、すべての出力はそのコマンドにパイプされます。これにより、実行されたプログラムのリダイレクトに影響を与えることなく、デバッグ出力をプログラムに簡単にパイプできます。 [… ]
(源泉、強調内)
あなたのコマンドは次のとおりです
strace -o '|vim -' file.out
引用または|
エスケープする必要があります。それ以外の場合、シェルはパイプを構築しようとします。別のオプションはいくつかのシェル!
です。保護されなければならないしかも。
strace
走ってsh
。sh
上記vim
の問題が修正されました。それぞれ:
これら3つのプロセスは同じプロセスグループに属します。
strace
フロントにいる場合はフロントにありますvim
。対話型(外部)シェルは、終了後にのみ端末から読み取りを試みます
strace
。sh
vim