時々、cat
バイナリ データを誤って入力したり、ncurses プログラムがクラッシュしたりします。さまざまな理由により、端末の状態が悪くなり、手動による操作が必要になりますreset
。このような状況は頻繁に発生します。
このような悪い状態には、エコーなし、すべてを中国語のゴミに変換する、その他さまざまなことが含まれます。
シェルが制御を取り戻したときに、ターミナルの設定(ハードリセットやクリーンスクリーンなどなし)が確実に復元されるようにする簡単な方法はありますか?
そうですbash
が、Terminal.app
この問題はほぼ普遍的だと思います。
答え1
あなたが言及した問題はさまざまなレイヤーで発生しており、そのうちのいくつかだけが「エスケープ コード」で解決できます。
端末エミュレーションの代替文字セット
端末によくある問題として、「(一部の)小文字が記号や線画文字として表示される」というものがあります(この他のSOの質問)。これはあなたの「中国語のゴミ」問題とは関係ないかもしれませんが、私が見た中で最も近いものです。また、ほぼすべての 8 ビット データ ストリームを UTF-16 でエンコードされたテキストとして解釈するときに、「中国語のゴミ」に遭遇する可能性もあります。通常、これはリセットする必要のある「厄介な」問題ではないため、おそらくあなたが見ている問題ではありません。
「線描画文字で停止する」問題は、通常、ターミナル エミュレータに意図しない制御シーケンスを送信した場合 (または、代替文字セットに切り替えた後にターミナルをリセットする前にプログラムを停止した場合) に発生します。これは、バイナリ データが表示され、バイト ストリームに代替文字セットを選択するターミナル制御シーケンスが含まれている場合に発生することがあります。
これは、1バイト(0x0e、参照)だけなので、ほとんどのVT-100スタイルの端末で簡単にトリガーできます。以前リンクしたSOの質問に対する私の回答)。この状態をリセットするための制御シーケンスも 1 バイト (0x0f; 多くの場合、 (++ と入力するか、 と直接入力) を介して生成さecho ^V^O
れます。 echo
ControlV ControlOprintf '\017'
プロンプトに 0x0f バイトを含めることで、このタイプの問題を解決できます。**「
中国語のゴミ」が他の何らかの問題によるものである場合は、別の解決策がある可能性があります。
PS1="\[\017\]… "
と\[
は\]
伝えるためにありますバッシュ境界文字は印刷されない。これによりバッシュ「物理的な」カーソル位置を正確に把握します (これは、コマンド ライン編集機能を使用するときに適切に再表示するために重要です)。
イグナシオ・バスケス・エイブラムスが指摘しているように彼の答え希望する制御シーケンスを取得する別の方法は、入力する指示:
tput rmacs
この方法を使用すると、PS1 を変更することなく、上記のコマンドを PROMPT_COMMAND に配置することができます。
PROMPT_COMMAND='tput rmacs'
TTY (termios) オプション
「エコーなし」の問題***は、ターミナル エミュレータをターミナル ウィンドウ内で実行されるすべてのプログラムに接続する OS ベースの tty デバイスのオプションの予期しない設定によって発生します。これは、対話型テキスト UI プログラムにバグ、クラッシュ、または強制終了があり、tty を元の状態に復元できないことが原因であることがよくあります。
これらの設定は、スティコマンド。この種の問題は、ttyオプションがソフトウェアAPIを介して構成されるため、「エスケープコード」では解決できません(tcsetattr(3)そしてターミオス(4)) は、一般的にはstty sane
良いリセット メカニズムです。
*** また、「^C/^Z/^/ がない」、「階段状の出力」(LF を受信しても自動 CR が行われない)、その他の問題もあります。
リセット
のリセットコマンドは通常、両方のタイプの問題に役立ちます。このコマンドは、通常、代替文字セットの問題を修正する端末初期化制御シーケンスを送信し、tty オプションを適切な値にリセットします。
問題はリセット問題は、一部のシステムでは追加のメッセージも表示されることです(例:「Erase is …」、「Interrupt is …」)。おそらく、これらのメッセージを毎回のプロンプトの前に表示したくないでしょう。リセットメッセージと制御シーケンスを別の場所に送信する (たとえば、一方は stdout に送られ、もう一方は stderr に送られる) と、メッセージをフィルタリングできる可能性があります (たとえば、PROMPT_COMMAND='reset 2>/dev/null'
(下記を参照)、プロンプトに ^O を入力するのをスキップします)。
^Oとstty sane
でバッシュパラメータをPROMPT_COMMAND
コマンドに設定し、バッシュプライマリプロンプトを表示する前に if を実行します。stty sane
ここにすべての呼び出しを入れて、プロンプトに ^O を入れることができます:
PROMPT_COMMAND='stty sane'
PS1="\[\017\]… "
繰り返しになりますが、PS1の変更を避けて(そしてVT-100スタイル以外の端末を扱うために)入力する(Ignacio Vazquez-Abrams 氏の提案による):
PROMPT_COMMAND='stty sane; tput rmacs'
答え2
置く
echo -n "$(tput rmacs)"
で$PROMPT_COMMAND
。
答え3
コマンドラインは少なくなりますが、xterm または任意のターミナルには常に「ボタン」リセットまたはハードリセットがあります。terminal.app の場合は、シェルメニューの下にあります。ハードリセットを送信するには、alt-command-r を押します。