シェルはコマンドに入力されたものを表示せず、「リセット」は機能しますが、どうなりましたか?


57

私の問題は、Bashシェルに入力した文字が表示されなくなることです。ただし、コマンドは読み取ります。

私はこの問題に何度も出くわしましたが、何が原因なのかわかりません。私はそれを解決する方法を知っていますが、問題から自分のやり方を「ブードゥーイング」しているとき、私は本当にそれが好きではありません。

この問題に遭遇した2つの方法を説明します。

私は特定のプロセス、http://pythonpaste.org/script/を実行していますが、時々それを停止したり、制御が壊れるとシェルに戻されます。その後、シェルにコマンドを入力すると、入力した文字が表示されません。Enterキーを押すと、コマンド送信されます。たとえば、次のとおりです。

  • 「ls」と入力します
  • 空のプロンプトのみが表示され、それ以上何も表示されません
  • Enterキーを押すと、ファイルのリストが表示されます。つまり、コマンド実行されます。
  • 「リセット」コマンドを与えると、シェルは再び正常に動作し始めます

これが起こる2番目の方法は、次のようなコマンドを入力したときです。

$ grep foo * -l | xargs vim

特定のパターンを持つファイルを見つけるためにgrepを使用し、grepの結果として生成されたすべてのファイルを開きます。これは魅力のように機能します(ただし、期待したほど高速ではありません)。しかし、Vimを終了すると、シェルに入力した文字が表示されなくなります。リセットコマンドで問題を解決します。

私の推測では、両方の問題には根本的な理由がありますが、私はその理由がどのように、または何であるかに困惑しています。

この問題の検索自体は、説明が曖昧で、厳密な検索用語がないため、問題があります。

編集

与える

stty --all

John S. Gruberのリクエストによるコマンドは、次の出力を提供しました(読みやすいように空白を編集しました)

speed 0 baud;
rows 53;
columns 186;
line = 0;
intr = <undef>;
quit = <undef>;
erase = <undef>;
kill = <undef>; 
eof = <undef>;
eol = <undef>; 
eol2 = <undef>; 
swtch = <undef>; 
start = <undef>; 
stop = <undef>; 
susp = <undef>;
rprnt = <undef>; 
werase = <undef>; 
lnext = <undef>; 
flush = <undef>; 
min = 0; 
time = 0;
-parenb 
-parodd cs8 
-hupcl 
-cstopb cread 
-clocal 
-crtscts
-ignbrk 
-brkint 
-ignpar 
-parmrk 
-inpck 
-istrip 
-inlcr 
-igncr 
-icrnl 
-ixon 
-ixoff 
-iuclc 
-ixany 
-imaxbel 
-iutf8
-opost 
-olcuc 
-ocrnl 
-onlcr 
-onocr 
-onlret 
-ofill 
-ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig 
-icanon 
-iexten 
-echo 
-echoe 
-echok 
-echonl 
-noflsh 
-xcase 
-tostop 
-echoprt 
-echoctl 
-echoke

2
この場合stty --all、質問に結果を入力して入力してください。エコーは、オフにされるtty特性です。Vimは実行中にこれを行い、ターミナルもrawモードにします。終了すると、ターミナル設定自体がリセットされます。iたとえば、vimが実行されているときは、エディターを挿入モードにするコマンドをエコーし​​たくありません。これらの設定は、入力したものをどのように処理するかをttyデバイスに伝えます。Vimが実行されているものの、それはなど、エコーされるべきエコーの世話をする
ジョン・グルーバーSを

Zopeをフォアグラウンドで実行していて、ipdbデバッグセッション中にZopeを停止すると(CTRL + Cで)同じ症状が現れます。
マークヴァンレント

私はあまりにもその問題を持っていると思います@MarkvanLent
ニールス・ボム

@JohnSGruber stty --all私の質問にの出力を追加しました。前もって感謝します!
ニールス・ボム

回答:


68

シェルまたはシェル内のほとんどのプログラムを実行すると、入力したものはすべて、カーネルのttyサブシステムによってユーザーの端末にエコーバックされます。文字の消去、Ctrl + R、Ctrl + Zなどのその他の特別な処理もあります。

コマンドラインから実行する特定のプログラム(特にエディター)は、これを必要としないか、必要としません。このため、この動作を望まないというtty(端末)デバイスに対するIOCTL呼び出しでカーネルに信号を送ります。彼らはまた、特別なキャラクターに特別なことをさせたくありません。代わりに、カーネルに「raw」モードを要求します。特に、vimのようなエディターはさまざまな「エコー設定」をオフにします。これはすべて、コンピューターのシリアル回線上の実際のtty端末、Alt + Ctrl + F1の仮想端末、またはGUIでgnome-terminalのようなものを実行したときに得られる実際の仮想端末に適用されます。

そのようなプログラムは、たとえば、エディタの終了コマンドを入力するか、(Control + Cから)信号を取得するなどして、使用する仮想ttyで変更するモードをリセットすることになっています。

彼らがこれを適切に行わなかった場合、ttyはあなたが発見した面白い状態のままになります。プログラムは端末のリセットに失敗するreset可能性があるため、ユーザーが回復できるようにコマンドが作成されました。

実行中のpythonソフトウェアが割り込みによって混乱していると思います。そのプログラムは端末をリセットする機会を得ていないか、単にリセットに失敗していると思います。

vimの場合、例を実行すると、説明したのと同じ動作になります。「Vim:警告:入力は端末からではありません」というメッセージも表示されます(リセットすると消えます)。これは、vimがシェルから正常に開始されないためです。代わりに、「grep」および「xargs」コマンドは、greptto からファイル名を渡すために、通常はttyが占有する標準入力を使用していますxargs

投稿された出力にstty -aは「-echo」が表示され、これが問題であることも確認できます。シグナルを適切に処理できないような方法でvimを強制終了した場合、おそらく同じ問題が発生するでしょう。

この問題はhttps://stackoverflow.com/questions/3852616/xargs-with-command-that-open-editor-leaves-shell-in-weird-stateの別の場所で説明されています

vimの場合の解決策は、xargsを避けて代わりに使用することです:

 vim $(grep foo * -l)

ここでは、ファイルのリストはxargsの場合と同様にシェルによって作成されますが、シェルはttyに直接接続されているvimを呼び出しています。エラー出力ファイルに警告メッセージが送信され、vimはtty設定を正しく設定およびリセットします。

複数の参照ここでは、別の興味深い1 こちら。別の興味深い解決策は、https://stackoverflow.com/questions/8228831/why-does-locate-filename-xargs-vim-cause-strange-terminal-behaviourへの回答に記載されています


徹底的な説明をありがとう。これが機能しない完全な理由はかなり深いウサギの穴(tty、ioctlなど)のように見えるため、完全に理解できるとは言えませんが、もうブードゥー教ではないので、もう一度ありがとう!
ニールス・ボム

完了するには、grep foo * -l | vim -問題なく実行できます。したがって、問題はgrepとxargsではなく、xargs にあると思います。同意しますか?
ニール

1
grepやxargsの問題ではありません。stdinがttyに設定されなくなったという事実に問題があります。これも同様に失敗します `true | vi / tmp / afile1。参考文献の1つでは、これらの状況ではstdinが/ dev / nullに設定されているため、vimはstdinをstdout(まだtty)に設定することに言及しています。その場合、vimはエコーやその他の設定を記憶してリセットできますが、そうではありません。これはvimの問題だと思います。
ジョンSグルーバー

私はこれに遭遇したので、これは非常に役に立ちました。ランダムに感じましたが、viで何かを行おうとしていたときに、きれいに終了しないか、パイプを使用していなかったのは間違いありません。
マイケルマシューズ14年

1
ありがとうございました!最後に、ctrl-cを実行した後、OS X bashで回復する方法を見つけましたgit add -p
スティーブヤンセン

0

システムで新しいユーザーを起動し(新しいクリーンユーザーを作成してログインすることを意味します)、問題が存在するかどうかを確認します。そうでない場合は、端末またはX11設定のいずれかです。


新しいユーザーを追加し、grep foo * -l | xargs vimコマンドでこれをテストしました。問題はまだ存在します。X11の設定が端末の反応にどのように影響するかを正確に理解していません。それについて詳しく説明していただけますか?ありがとう!
ニールス・ボム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.