web-dev-qa-db-ja.com

一部のツール(nanoなど)は、終了後に端末にコンテンツを残さないようにする方法を教えてください。

シェルでlessのようなページャーまたはnanoのようなエディターを使用するときはいつでも(シェルはGNU bash))、完全に説明できない動作が表示されますcatlsなどの他のツールで観察できる動作とは異なります。この動作がどのように発生するのかを確認したいと思います。

「説明するのは簡単ではありません」の動作は、通常、stdout/stderrへのすべての出力がターミナルエミュレータのバックバッファに記録されるため、lessまたはnano、出力はターミナルエミュレーターによって表示されますが、プログラムを終了すると、コンテンツは「魔法のように消えます」。

これらの2つの例を挙げます。

  • seq 1 200(バックバッファーで200行を生成)
  • seq 1 200 | less(200行を追加しますが、最終的には「クリーンアップ」し、バックバッファーには何も記録されません)

私の疑いは、ある種のエスケープコードが機能していることです。この観察された動作の違いの説明を私に指摘してくれる人に感謝します。

一部のコメントと回答は、振る舞いを変更したいという私の願望のように語られているため、これは「知っておくと良いでしょう」ですが、実際に望まれる回答は、メカニズムの説明であり、変更方法ではありません。

36

ここには2つの世界観があります。

  • Termcap/terminfoを使用するプログラムに関する限り、端末には2つのモードカーソルアドレッシングモードおよびスクロールモードの可能性があります。後者は通常のモードであり、行と列のアドレスで画面上でカーソルを移動する必要がある場合、プログラムはカーソルアドレス指定モードに切り替わり、画面を2次元のエンティティとして扱います。

    termcapとterminfoは、プログラムが見るこの世界観を、端末から見た世界観に変換します。

  • 端末(エミュレートまたは実数)に関する限り、2つの画面バッファーがあり、常に1つだけが表示されます。プライマリ画面バッファーと代替画面バッファーがあります。プログラムによって発行された制御シーケンスは、2つの端末を切り替えます。
    • 一部の端末(通常はエミュレートされる端末)では、termcap/terminfoの使用に合わせて代替画面バッファーが調整されます。これらは、カーソルアドレス指定モードへの切り替えの一部が代替画面バッファへの切り替えであり、スクロールモードへの切り替えの一部がプライマリ画面バッファへの切り替えであることを認識して設計されています。これは、termcap/terminfoが物事を翻訳する方法です。そのため、これらの端末は、代替画面バッファーが表示されているときにスクロールするユーザーインターフェイスウィジェットを表示せず、その画面バッファーのスクロールバックメカニズムを備えていません。
    • 他の端末(通常は実際の端末)の場合、代替画面バッファはプライマリとほとんど同じです。どちらも、サポートする内容はほぼ同じです。いくつかのエミュレートされた端末がこのクラスに分類されることに注意してください。たとえば、Unicode rxvtには、プライマリ画面バッファと代替画面バッファの両方のスクロールバックがあります。

全画面テキストユーザーインターフェースを表示するプログラム(vimnanolessmcなど)は、termcap/terminfoを使用して、起動時にカーソルアドレス指定モードに切り替え、スクロールに戻ります一時停止、またはシェルアウト、または終了するときのモード。 ncursesライブラリはこれを行いますが、termcap/terminfoの上にさらに直接ビルドする非ncurses使用プログラムも同様です。

lessまたはvimによって提示されるTUI内のスクロールは、scrollbackとは関係ありません。これはこれらのプログラム内に実装されており、スクロールすると適切にフルスクリーンのテキストユーザーインターフェイスが再描画されます。

これらのプログラムしないでください代替画面バッファに「コンテンツを残さない」ことに注意してください。端末は単に、彼らが残したものをもはや表示していません。

  • これは、一部のプラットフォームのUnicode rxvtで特に顕著で、カーソルアドレッシングモードに切り替えるためのtermcap/terminfoシーケンスは、代替画面バッファーを暗黙的にクリアしません。したがって、複数のそのようなフルスクリーンTUIプログラムを連続して使用すると、新しいプログラムが出力を書き込むまで(少なくともlessが最も顕著になるまで)、最後のプログラムによって残された代替画面バッファーの古い内容が表示される可能性がありますパイプラインの終わりに)。
  • Xtermを使用すると、ターミナルエミュレーターのGUIメニューから代替画面バッファーの表示に切り替えて、そこにコンテンツを表示できます。

実際の制御シーケンスは、関連する標準が呼び出すものですset private mode制御シーケンス。関連するプライベートモード番号は、47、1047、1048、および1049です。代替画面バッファとの切り替えに加えて、それぞれが暗示する追加のアクションの違いに注意してください。

参考文献

41
JdeBP

Cursesと呼ばれるライブラリは、使用している端末タイプを認識し、正しいエスケープシーケンスを送信します。そこにある端末は、別の垂直バッファと、より多くの制御を可能にするモードに切り替えるように求められます。

5
ctrl-alt-delor

いくつかの方法で、これに非クリアを追加できます。 -X引数を指定してlessを呼び出すと、画面がクリアされなくなります。

以下のコマンドラインの$記号に注意してください。通常のユーザーの端末プロンプトを指定します。

$ seq 1 200 | less -X

それが望ましい動作であれば、lessをこのデフォルトにエイリアスすることができます:

$ alias less='less -X'

他のプログラムにも同様の回避策があります。

または、各アプリケーションを個別に構成するのではなく、独自の端末定義を追加できます。この場合、この例ではxterm-noclearと呼びます。

次の手順を実行して、新しいxterm定義を作成します。

$ infocmp -I xterm > xterm-noclear.src
$ gedit xterm-noclear.src

エディタの2行目をxtermからxterm-noclearに変更します。

rmcupおよびsmcupを検索して画面をクリアする指示を削除し、次の2つの指示を削除します。

smcup=\E[?1049h,

そして

rmcup=\E[?1049l, 

ファイルを保存し、次のようにターミナル定義を追加します。

$ tic ~/xterm-noclear.src

これをシステム全体で利用可能な端末定義にすることができます。

$ Sudo tic ~/xterm-noclear.src

これでこれをTERMで使用できます:

$ export TERM=xterm-noclear
4
L. D. James