安全な猫はいますか?

安全な猫はいますか?

時々、カールまたはローカルファイルシステムからバイナリを取得します。ほとんどの場合、破損した端末は以下を使用して修理できます。初期化。他の場合、特にバイナリが大きい場合、端末は次の出力を印刷しながら数分間停止します。

2c1

また〜として知られています

c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;
2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;

このシーンについて3つの質問があります。

  1. 2c1 とはどういう意味ですか?端末がこれを印刷するのはなぜですか?
  2. cat対話型セッションでこれらの悪い動作が実際に防止された状況を見たことがありますか?
  3. そのような猫(ceeまたはgolang)をプログラムする方法に関する提案はありますか?

私の初期の本能は、これを検出するためにcatを関数で包むことでしたが、これはかなり難しくて極端なケースが多いことにすぐに気づきました。

function cat() {
    # warn user if
    #   - argument 1 is a large  executable 
    #   - argument 1 to the previous command in the a pipe-chain looks like a large binary
    # abort if
    #   - session is interactive and we are able to detect 2c1 garbage
}

実用的な解決策は、「安全でない」入力を見るときは常にless(LESSPIPEを使用)を使用することですが、この質問はポケットベルとは何の関係もありません。チューブの数が徐々に減少していることを知っています。私は毎日積極的に使用しています。たぶん少ない+少ない制御することができますこの問題に対する解決策は、Lessの著者が約20〜30年前に同じ問題を実装したことです。

しかし、catはさまざまな点で「呼び出し元」とは異なります。最も重要なのは、catがインタラクティブではないということです。これは私に多くの意味があります。

less + lesspipeの提案は実際には非常に素晴らしいです(IMHO)。しかし、私は制御文字の特性、特殊なエスケープシーケンス、およびさまざまな端末がこれらの入力を処理する方法に興味があります。

私は、制御文字の技術的詳細と、端末やシェルが「ゴミ」と制御文字を解釈する方法に興味があります。私は「この問題をどのように解決しますか?」と尋ねるのではありません。私は「なぜ端末がバイナリファイルをこのように処理するのか」と尋ねました。

答え1

私はこれをバイナリについて警告するために使用し、lessいくつかのシステムではさまざまなタイプを処理します(例えばCentOS 7では、less file.rpmRPMでファイルを表示できます。私はこれが「レスパイプ」と呼ばれると信じています。

また、次にこれが発生した場合は、正常にreset戻ることができますtput reset。彼らは端末にエスケープシーケンスを送信してデフォルトの通常状態にリセットするように指示し、stty sanettyデバイスファイルの設定を通常のデフォルトに変更するのと同じことを行います(バイナリダンプはこれらの設定に影響を与えてはいけません)。resetまた、ttyデバイスファイルのターミナルまたはターミナルエミュレータウィンドウサイズの概念(報告されているようにtty size)を変更し、それに対するターミナルクエリをサポートします。

答え2

誰も「文字列」に言及していません。文字列はcatとまったく同じではありませんが、隣接するテキストデータのテキスト文字列のみを印刷するので、端末で見るのがより安全です。通常はbinutilsパッケージに付属しています。これは、印刷されたデータからバイナリ出力を取得しないようにすばやくチェックする便利なプログラムで、連続したバイナリデータを表示したい場合にも便利です。デフォルトでは、4つ以上のASCII文字を含むテキストの連続部分のみが印刷されます。これは -n オプションを使用して調整できます。

答え3

シリアルラインまたは擬似ttyデバイス(シリアルラインをエミュレートする)を介してターミナルまたはターミナルエミュレータと対話できます。

カーネルには、いくつかの変換を実行するソフトウェアモジュールがありますが、後で簡単に説明しますが、通常は次のことを行います。

  • このシリアルラインを介してバイトストリームを端末に送信します。端末は、それを画面にレンダリングする文字または動作を変更するための特別なガイドラインとして解釈します。
  • その代わりに、端末は、ユーザーが入力した内容または受信したいくつかの制御クエリに応答してコンピュータに通知するために、シリアル回線の他の回線を介してコンピュータにバイトストリームを送信します。

たとえば、端末はISO8859-1(latin1端末とも呼ばれる)で構成できます。つまり、0x53 0x74 0xe9 0x70 0x68 0x61 0x6e 0x65を受信すると、端末は画面の現在のカーソルS位置にあると解釈されます。代わりに、ユーザーが入力すると、端末は0x53バイトを送信します。téphaneS

0〜0x1fの範囲のバイト値は、次のように解釈されます。コントロール数値。つまり、グリフで表現されず、むしろ特別な意味を持つ。

たとえば、

  • 0x7(BEL)オーディオまたはビジュアルアラートの生成
  • 0x8(BS)カーソルが左に移動します。
  • 0xa(LF)カーソルが下に移動します。
  • 0xd(CR)はカーソルを画面の最初の列に移動します。
  • 0x9(TAB) カーソルを次のタブに移動

この範囲には32個の制御文字のみがあり、ほとんどの端末にはこれを制御するためのより多くの機能または方法があります。したがって、これに加えて、以下よりも多くを送信できます。一つ端末を制御するバイトです。ほとんどの端末とシーケンスの場合、最初のバイトは0x1b(ESC)で、その後に1つ以上のバイトが続きます。

たとえば、上記のようにカーソルを左または下に移動する制御文字はありますが、右または上に移動する制御文字はありません(元のテレタイプマシンでは右側が「スペース」で構成されていますが、CRTでは端末ではカーソルの下に消去してテレタイプを使用すると、紙詰まりが発生する可能性があるため、これらの端末にはエスケープシーケンスが必要ですRight。端末から送信されるバイトシーケンスでもありますUp。)

端末でサポートされるエスケープシーケンスは次のようになります。

  • テキスト、背景色、その他のグラフィックレンダリングプロパティの変更
  • 文字セットを変更します。たとえば、latin1にはギリシャ語文字がなく、端末(Unicodeの前から現在まで)は、異なる言語のアルファベットまたはブロック図文字を表示するために別の文字セットに切り替えることをサポートしています。
  • タップ停止位置の設定
  • カーソルの位置、色、ウィンドウのタイトル、サイズなどの情報を端末で照会できます。
  • 入力の処理方法に影響を与える可能性があります。たとえば、一部の端末は、Shift+を押すAと0x41(ASCII)文字を送信せずに、対応するA修飾子(shift、alt、ctrl ....)とキーの一連のバイトを送信するモード入力をサポートしています。コード情報がエンコードされます。
  • 一部のX11端末エミュレータは、エスケープシーケンスを認識してフォント、ウィンドウのサイズを変更し、JPEG画像を表示し、画面の内容をプリンタに送信することができます。

テキストファイルには通常、グラフィック文字を表すバイト(またはUTF-8または他のマルチバイト文字セットの場合はバイトシーケンス)のみがあります。ただコントロールテキストファイルで見つけることができる文字は、NL(0xa、別名LF)とTAB(0x9)です。

これはcat file.txt単にcat内容を読み、file.txt標準出力に書き込みます。 stdoutがシリアルまたは疑似ttyデバイスファイル(たとえば)で、ターミナルラインルールがここにプッシュされると、/dev/ttyS0ターミナル/dev/pts/0エミュレータの対話型シェルでコマンドを実行するかのように、ラインルールはこれらのNLをCRに変換します。 +NL(NLNLはCRNLNLに翻訳できます)、端末はCRNLを受信した後、カーソルを最初に移動してから下に移動します。

したがって、ファイルのテキストが端末の文字セットにエンコードされると、ファイルの内容のテキストが端末画面に表示されます。

実行可能ファイルまたは他の任意のバイナリのバイトは文字を表すためのものではなく、0から31の範囲の値を含む任意の値を持つことができるため、端末に送信されると、端末は指示どおりに実行されます。これを制御文字として実行して解釈すると、上記の操作の異常を実行し、完全に使用できなくなる可能性があります。

これを防ぐために、まずこれらのファイルを端末に送信しないでください。これは、言葉にならない場合、またはファイルがテキストファイル(または意図されたファイル)である可能性があるかどうかわからない場合です。ユーザーがそのまま見ることができます)端末のエスケープシーケンスを含める故意に端末で解釈されているかどうかにかかわらず、制御文字(最小TABおよびNLを除くすべての文字)を削除したり、視覚的にグラフィカルに表現したりするツールを使用できます。

これはまさに多くの実装サポート-vとオプションの機能です。ここで、NLとTABを除くすべての文字は、非ASCII文字の一般的な視覚表現であるバイト0〜31と0x7f、バイト0x80〜0x9fと0xff、バイト0xa0〜0xfeの一部の表現に変換されます。そしてTAB(に変更)でのみ機能します。-tcat-v^XM-^XM-X-t^I

あるいは、基本的にこれを実行するか、less同じポケットベルを使用することができます(少なくとも/ rawオプションを使用しない限り)、ASCII以外の文字を変換しないという点でもう少しスマートです。そのロケールのグラフィック表現の色付けまたはハイライトモードを使用して、どのバイトが変換されたかをより明確に表示します。vimview-r-R

または。hexdump -Cxxd

lwhichコマンドがより明示的な方法で同様の操作を実行し、標準(反対)の場合も参照してください。sedcat -vtecat -vte

sed -n l < a-file

答え4

  • うん、若い見習い。
$ cargo search bat 
bat = "0.23.0"            # A cat(1) clone with wings.
  • ところで先生、物は何ですか?
$ cargo --help |any install rust 
Rust's package manager
      --list                List installed commands
      --explain <CODE>      Run `rustc --explain CODE`
    install     Install a Rust binary. Default location is $HOME/.cargo/bin
    uninstall   Uninstall a Rust binary
$ cargo install bat
(...)

マスター:バイナリファイルを使用しようとすると、batこれが発生します。

$ bat `which bat`
[bat warning]: Binary content from file '/home/jaroslav/.cargo/bin/bat'
will not be printed to the terminal (but will be present if the output
of 'bat' is piped). You can use 'bat -A' to show the binary file contents.
  • ドジェ:先生、打撃に不利益がありますか?
  • マスター:はい、大容量ファイルを処理すると速度が遅くなる可能性がありますが、これは部分的に構造化された構文を強調するためです。 --style=plain --color=never のように無効にできます。
  • ドジェ:では、先生、catがターミナルに出力する奇妙な文字はどうですか?
  • マスター:これは、ターミナルがANSIエスケープコード(内部ターミナルコマンド)のように見えるすべてを喜んで受け入れて解釈し、コマンドが言うように実行しようとするために発生します(そのコマンドが実装されている場合)。簡単な紹介については、以下を確認してください。Ansiカラーエスケープシーケンスリスト

この動作を再現する方法は次のとおりです。

$ echo -ne "\u1B\u5B\u63" | xxd
00000000: 1b5b 63                                  .[c

$ echo -ne "\u1B\u5B\u63" 
^[[?1;2c

$ 1;2c

関連情報