有安全的貓嗎?

有安全的貓嗎?

我有時會從curl 或本機檔案系統中取得二進位檔案。在大多數情況下,損壞的端子可以用以下方法修復重置。在其他情況下,特別是如果二進位檔案很大,終端將卡住幾分鐘列印輸出,如下所示:

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;

關於這個場景我有三個問題;

  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 的建議實際上非常好(恕我直言),但我更關心控製字元的本質、特殊的轉義序列以及不同的終端如何處理這些輸入。

我對控製字元的技術細節以及終端或 shell 如何解釋「垃圾」和控製字元更感興趣。我並不是問「你將如何解決這個問題」。我問「為什麼終端機要這樣處理二進位檔案」。

答案1

我會用less它來警告二進位文件,並且在某些系統上可以處理各種類型(例如在 CentOS 7 上,我可以less file.rpm查看 RPM 中的檔案)。我相信這就是所謂的「lesspipe」。

另外,下次發生這種情況時,您可以嘗試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),後面跟著一個或多個位元組。

例如,雖然有控製字元可以將遊標向左或向下移動,如上所示,但沒有控製字元可以將其向右或向上移動(最初,在電傳打字機中,向右將用「空格」完成,但在CRT 終端機會擦除遊標下的內容,而且您不會使用電傳打字機,因為這可能會造成卡紙),因此必須為這些終端引入轉義序列,在大多數終端上分別為0x1b 0x5b 0x43和0x1b 0x5b 0x41 (順便說一句,這也是許多終端在按下對於具有此類鍵的終端Right和)。Up

現在,終端支援的轉義序列包括:

  • 變更文字或背景顏色以及其他圖形渲染屬性
  • 更改字符集。例如,latin1 中沒有希臘字符,終端(從 Unicode 出現之前至今)支援切換到不同的字符集以顯示其他語言的字母或方框圖字符。
  • 設定製表位的位置
  • 可以從終端查詢訊息,例如遊標位置、顏色、視窗標題、大小...
  • 會影響輸入的處理方式。例如,某些終端支援輸入一種模式,例如,在按Shift+A時,它不會發送 0x41 (ASCII A) 字符,而是發送一系列字節,用於對有關修飾符(shift、alt、ctrl .. .)和鍵碼的資訊進行編碼。
  • 一些 X11 終端模擬器可以識別轉義序列來更改字體、視窗大小、顯示 JPEG 影像、將螢幕內容傳送到印表機...

在文字檔案中,通常只有代表圖形字元的位元組(如果是 UTF-8 或其他多位元組字元集,則為位元組序列)。唯一的控制您在文字檔案中找到的字元是 NL(0xa,又稱 LF)和 TAB(0x9)。

當您這樣做時cat file.txtcat只需讀取 的內容file.txt並將其寫入其標準輸出。如果 stdout 是一個串行或偽 tty 設備文件(例如 ) /dev/ttyS0/dev/pts/0並且將終端行規則推送到其上,就像您從終端仿真器中的交互式 shell 運行該命令一樣,則行規則會轉換這些 NL到CR+NL(儘管NLNL 可能被翻譯為CRNLNL),因此終端在收到CRNL 後會將遊標移至開頭,然後向下移動。

因此,如果檔案中的文字以終端機的字元集進行編碼,則檔案內容中的文字將顯示在終端螢幕上。

現在,可執行檔或其他隨機二進位檔案中的位元組並不旨在表示字符,它們可以具有任何值,包括0 到31 範圍內的值,因此當發送到終端時,終端將執行它所告知的操作並將它們解釋為控製字符,這可能會使其執行上面列出的任何操作以及更多操作,並使其完全無法使用。

為了防止這種情況,首先不要將這些文件發送到終端,因為這沒有意義,或者如果您不知道文件是否可能是文字文件(或打算由用戶逐字查看的文件)帶有轉義序列的終端故意的無論是否由終端解釋,您都可以使用一個工具來刪除控製字元(至少是除 TAB 和 NL 之外的所有字元)或為它們提供視覺化圖形表示。

這就是許多實現所支援的-v和選項所做的事情。其中,除了 NL 和 TAB 之外的所有字元都轉換為位元組 0 到 31 和 0x7f、位元組 0x80 到 0x9f 和 0xff 以及位元組 0xa0 到 0xfe 的某種表示法,這些是非 ASCII 字元的常見視覺表示。並且僅適用於 TAB(更改為)。-tcat-v^XM-^XM-X-t^I

或者您可以使用尋呼機,例如lessvim,它view默認執行此操作(至少只要您不使用-r/ -Rraw 選項)並且更聰明一點,因為它們不會轉換非 ASCII 字元意味著在您的語言環境中具有圖形表示,並透過使用著色或突出模式更清楚地顯示哪些位元組已被轉換。

或者,您可以使用專用於預覽非文字檔案的工具,例如hexdump -Cxxd

另請參閱which 命令以更明確的方式執行類似於和 is standard (與 相反)l的操作: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

相關內容