像 top 這樣的指令如何更新輸出而不在控制台中追加?

像 top 這樣的指令如何更新輸出而不在控制台中追加?

我透過 PuTTY 終端模擬器使用 SSH 連接到遠端 Linux 伺服器。我注意到我運行的命令和控制台上的輸出不斷附加在終端機視窗中。我的意思是,當我使用滾動條並向上/向下滾動時,我可以看到我之前運行的命令及其輸出,就像在列印紙上一樣。但是,某些命令(例如top不斷更新輸出)不會在控制台上顯示為附加。它是如何運作的?

答案1

這裡可能有兩種機制在運作。

一種是使用 ANSI 轉義碼(在某些情況下還有其他非 ANSI 程式碼),正如 Martin Prikryl 在他們的回答中提到的那樣,來實現基於文字的偽圖形介面。至少需要兩個特定的 ANSI 轉義碼,^[[2J,它會擦除螢幕上的所有內容,以及^[[;H,它將遊標移動到螢幕的左上角。透過組合這些,您可以一一寫出每個「幀」的內容,而無需添加到回滾緩衝區。大多數應用程式實際上使用的不僅僅是這些(例如,有一組用於在任意方向上移動遊標的程式碼,並且使用這些程式碼來跳過螢幕上應該為「空」的部分是很正常的)。在實踐中,大多數(但絕不是全部)較大的應用程式使用 libcurses(或更常見的是 ncurses)或直接等效項來為它們處理所有這些。

另一種可能性通常與使用 ANSI 轉義碼相結合來操作螢幕內容,是最初由 xterm 提供的特殊功能,但現在由大多數不錯的終端模擬器廣泛實現,稱為備用螢幕緩衝區。有一對轉義碼(^[[?1049h^[[1049l)用於在此緩衝區和常規回滾緩衝區之間切換。透過在呈現文字 UI 之前切換到備用螢幕緩衝區,程式可以完全避免更改回滾緩衝區,這不僅可以防止您滾動而不必攔截通常滾動的擊鍵,還可以讓程式執行以下操作:讓您在程式在運行之前檢查現有的終端內容(並且可以更輕鬆地查看在打開全螢幕應用程式之前您正在做什麼)。

答案2

你所觀察到的是歷史發展的產物。

最早的交互終端是真實的電傳打字機;本質上是連接到電話線的電動打字機。 (有沒有想過為什麼 /dev/終端是按照它的命名方式命名的嗎? )您可以鍵入文字命令(使用 iirc,甚至一些基本的、笨拙的行編輯),然後會得到文字輸出。

當然,這些只能從左到右和從上到下移動。喔等等,這不是真的!他們可以使用 Ctrl-H 返回一個字符,然後再次鍵入它,使其變為粗體。看哪,這就是有些程式仍然這樣做為印表機設定文字格式。電傳打字機還有一些基本的控制代碼,如換行、換頁或響鈴。

如果只是為了拯救樹木,那麼使用基於 CRT 的終端的步驟是合乎邏輯的。但從那時起,每個終端(模擬器)都提供了電傳打字機的基本功能:除非另有說明(使用著名的轉義序列),否則接收到的7 位元ASCII 代碼(包括基本控制代碼)將被解釋為相應的字元或命令並從左到右、從上到下顯示,從終端維護的當前遊標位置開始。

但是,由於更聰明的終端實際上能夠在螢幕上的任意行/列位置顯示字符,因此它們都有一些方法透過控製程式碼序列以編程方式執行此操作,並且作業系統以某種方式配置為使用正確的序列。某些程序,特別是編輯器、shell 和其他互動式、使用者導向的程式(例如 top)使用此功能來控制整個螢幕。

這種「視覺模式」並不常見的原因是,簡單地輸出不帶有「修飾」的線性字元序列是非常通用的,同時足以滿足廣泛的輸出:您可以列印清單數據,這本質上仍然是帶有空格(空格、製表符、換行符)的連續字元序列。包含管道和設備的整個 Unix/Linux 生態系統都是圍繞著這個範例建構的。它允許您將 find、grep、cut 等“積木”插入在一起並自動處理文字訊息。如果輸出與定位和格式化命令混合在一起,那是完全不可能的。

答案3

大多數命令只是將行列印到終端。終端客戶端只是像古代行式印表機那樣列印這些行。回滾是一個表示無盡的紙從印表機出來。

但是終端客戶端(又名終端模擬器)可以做更多的事情,包括在螢幕上移動遊標,從而允許伺服器(遠端應用程式)在「終端螢幕」的任意點上進行列印。這就是topvi、 Midnight Commander 等應用程式用來實現全螢幕「GUI」介面(實際上是一個途易介面)。這些高級功能是使用實現的ANSI 轉義碼

相關內容