小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Cygwin系列(十):折騰終端1 | silaoA的博客

 看見就非常 2022-02-24

本文共5200余字,預(yù)計閱讀時間16分鐘,本文同步發(fā)布于知乎(賬號silaoA)和微信公眾號平臺(賬號偽碼人)。

關(guān)于終端的概念,已在 Linux Cygwin知識庫(一):一文搞清控制臺、終端、shell概念 中論述。UNIX/Linux系統(tǒng)對命令行有著天然的支持,Windows對命令行生態(tài)卻不怎么重視,本著死磕自己娛樂大家的精神,深度扒一扒命令行生態(tài)中的重要元素——終端。

0x00 終端的歷史演進

終端設(shè)備

UNIX上古時期,經(jīng)歷了電傳打字機(Teletype, tty)、電子視頻終端(Video Terminal,鍵盤+陰極射線管顯示器)用作終端設(shè)備(Terminal),通過RS232串口線連接主機,是計算機系統(tǒng)中的io外設(shè)。

在沒有圖形界面、只有文本字符的年代,為了更加靈活、友好地和用戶交互,終端設(shè)備逐漸支持顏色、高亮、光標移動、清屏等多種效果,設(shè)備廠商定義一些特殊字符來表征這些效果,因為不是真正的輸出文本內(nèi)容,也被稱為轉(zhuǎn)義字符控制字符,比如在shell提示符變量PS1、ls輸出顏色控制變量LS_COLOR中,經(jīng)??吹降摹盶033[34m”或”\e[34m”。這些特殊功能以函數(shù)庫(termcap/terminfo)的形式提供給開發(fā)者,方便開發(fā)者調(diào)用。但是如果每個廠家都來這么一套函數(shù)庫,而且各家規(guī)范也不一致的話,開發(fā)者用起來就比較頭疼,程序在不同終端上兼容性也差。美國國家標準學(xué)會(American National Standard Institute,ANSI)牽頭制訂了包括ASCII在內(nèi)的一系列規(guī)范,解決計算機、終端設(shè)備等之間數(shù)字信息問題,ANSI采用了ANSI X3.64規(guī)范,提出了“ANSI Escape Sequence”的概念(以下稱“ANSI轉(zhuǎn)義序列”),見維基百科 ANSI_escape_code。

1978年,Digital VT100成為首個支持ANSI Escape Sequence的終端設(shè)備,隨著VT100大獲成功,越來越多的終端設(shè)備兼容VT100,VT100成為了事實標準,相關(guān)標準被UNIX、Linux所支持和繼承,甚至陰極射線管顯示器支持80行×24列字符的尺寸標準也被保留。

偽終端

隨著計算機造價變低、PC普及,終端設(shè)備退出歷史舞臺,特別是圖形界面(GUI)技術(shù)廣泛應(yīng)用后,終端模擬器(Terminal Emulator)開始替代它的位置,以下不刻意區(qū)分術(shù)語“終端”和“終端模擬器”。但是命令行程序還是期望處于真實的終端設(shè)備環(huán)境中,總不能把以前所有的命令行程序中的io功能、ANSI轉(zhuǎn)義序列等全部改掉,UNIX/Linux內(nèi)核發(fā)展出了偽終端(pseudo tty,縮寫為pty)設(shè)備順應(yīng)這一趨勢。

UNIX/Linux系統(tǒng)上的終端模擬器就順著pty這條線發(fā)展,比如X Window System的標配程序xterm,其他諸如rxvt、Gnome圖形環(huán)境標配的Gnome Terminal、KDE圖形環(huán)境標配的Konsole等,基本都是在xterm基礎(chǔ)上發(fā)展而來。Cygwin通過模擬UNIX,也兼容了pty(也許只能部分兼容,未實考)。

經(jīng)??梢钥吹浇K端模擬器的配置中,涉及“終端模式”或者“兼容模式”,可設(shè)置的選項包括“VT100”、“ANSI”、“xterm”等。具體屬性信息,可通過stty命令顯示。

0x01 Windows對終端的支持

Windows自win95起就已成為成熟的、基于GUI的操作系統(tǒng),但也未拋棄命令行程序。Windows將應(yīng)用程序分為Console應(yīng)用程序(也就是命令行程序)和GUI應(yīng)用程序,兩類應(yīng)用程序所允許調(diào)用的Windows API范圍不同,如果用過微軟的Visual C++、Visual Studio開發(fā)工具,想必還記得在新建工程時可選工程類型就包括這兩種。

由于設(shè)計理念不同,Windows內(nèi)核不支持Single Unix Specification中規(guī)定的終端、偽終端設(shè)備,也不支持ANSI轉(zhuǎn)義序列,但提供了Windows Console組件和相應(yīng)配套的API。

Windows Console組件

利用Windows Console組件,可以給命令行程序提供一個(模擬的)終端環(huán)境。從Windows 7開始,出于安全考慮,Windows Console組件整合為由以下幾個二進制文件組成:

  • conhost.exe,是一個標準的Win32 GUI應(yīng)用程序,在C:\WINDOWS\system32路徑下,提供一個模擬終端的窗口,負責維護存儲鍵盤、鼠標、觸屏板事件的輸入隊列,和存儲命令行輸出文本及顯示屬性的輸出隊列,支持ANSI轉(zhuǎn)義序列解析、處理,管理Console窗口的布局、尺寸、位置等;
  • condrv.sys,是內(nèi)核態(tài)驅(qū)動,為conhost.exe和命令行程序提供通信通道,傳遞IOCTL消息。
    Win10 1803上的Console架構(gòu) 圖片<a name='來源+知乎'></a><font style='color: red'>來源</font>:微軟博客Win10 1803上的Console架構(gòu) 圖片來源:微軟博客

Windows Console與UNIX/Linux上的pty、終端模擬器,初看起來像,但本質(zhì)截然不同。

  1. Windows Console與命令行程序之間,傳遞的是API調(diào)用和IOCTL消息數(shù)據(jù),即使是嵌在文本中的ANSI轉(zhuǎn)義序列也被轉(zhuǎn)換為等效的Windows API調(diào)用,而UNIX/Linux上的pty設(shè)備/終端模擬器與命令行程序?qū)_f的就是文本流。這是兩者設(shè)計思想的差異:在UNIX/Linux中,一切皆文件;而在Windows中,一切皆對象。
  2. Windows提供了pty設(shè)備、終端模擬器職責之外的功能特性,用于操作終端窗口,比如Windows選擇不信任命令行程序的開發(fā)者,為避免命令行程序生成ANSI轉(zhuǎn)義序列,提供等效的Console API調(diào)用,操控模擬終端窗口的外觀;再比如,為避免每個命令行shell重復(fù)實現(xiàn)命令歷史、命令匿名等基礎(chǔ)功能,Console API就實現(xiàn)了這些功能。
  3. 最操蛋的是,Windows強制規(guī)定命令行程序啟動后,只能連接到conhost實例,當命令行程序沒有父進程或父進程是GUI程序時(比如鼠標雙擊文件名啟動),Winodws新建一個conhost實例,強制通過condrv與之連接;當命令行程序父進程也是命令行程序時(比如在終端窗口中輸入文件名啟動),就繼續(xù)使用父進程已連接的conhost實例與之連接。

Windows Console的不足

由于上述第1點和第2點,Windows Console沒有必要支持ANSI轉(zhuǎn)義序列,事實上直到Windows 10,Windows Console才開始支持ANSI轉(zhuǎn)義序列直接解析,在此之前Windows Console無法和UNIX/Linux上的命令行程序傳遞能被雙方都接受的數(shù)據(jù),導(dǎo)致Windows Console局限在Windows平臺,UNIX/Linux上的終端模擬器也不能與遠程的Windows命令行程序連接。

由于上述第3點,雙擊C:\WINDOWS\system32\cmd.exe或在開始菜單點擊命令提示符、PowerShell等,Windows會新建一個conhost實例,并通過condrv建立通信通道,外觀表現(xiàn)就是新建了一個模擬終端的窗口,打印著cmdPowerShell的提示符,等待用戶輸入,容易被用戶誤認為cmd或命令提示符或PowerShell就是終端本身。在此糾正,他們都僅僅是解釋器,是常規(guī)的Windows命令行程序,扮演的是shell角色,與UNIX/Linux上的bash、zsh對等,也不是什么dos程序,而終端模擬器是Win32 GUI程序。此外,雙擊C:\WINDOWS\system32\conhost.exe文件名,或在終端窗口中輸入”conhost”,Windows會新建一個conhost實例,并且默認啟動一個解釋器,默認值通常是cmd,外觀表現(xiàn)就是打開了新的模擬終端窗口,里面打印著提示符,等待用戶輸入。

還是由于上述第3點,Windows不給第三方終端模擬器與命令行程序通信的機會,導(dǎo)致第三方終端模擬器的實現(xiàn)流程異常曲折。

鑒于這些不同,可以說Windows與UNIX/Linux的命令行生態(tài),是完全互不兼容的兩套。Cygwin作為UNIX兼容層,算是比較好的解決方案,盡可能抹平二者差異。

0x02 第三方終端模擬器

概覽

基于前一節(jié)內(nèi)容,可將終端模擬器分為2類:基于Windows Console組件的和基于pty的。

鑒于前一節(jié)所述第3點,基于Windows Console的第三方終端實現(xiàn)流程通常是:

  • 啟動conhost進程并將conhost窗口隱藏起來,比如將窗口移到負數(shù)坐標位置;
  • 繪制自己的一套UI,記錄按鍵、鼠標、觸屏事件,同時發(fā)送給conhost進程,最終傳遞給命令行程序,命令行程序照常執(zhí)行;
  • 抓取隱藏的conhost窗口上的命令行程序輸出的文本內(nèi)容、風格,再在自己的UI上渲染出來。
    以上流程,看起來就像是個非法軟件采集用戶輸入,同時也把輸出呈現(xiàn)在屏幕上,讓用戶誤以為是第三方終端模擬器連接了命令行程序,但在任務(wù)管理器中查看,必然可見conhost.exe。與此同時,如何直接解析ANSI轉(zhuǎn)義序列也需要第三方終端模擬器自己想辦法,或者抱Cygwin大腿。

基于pty的,通常都是抱Cygwin大腿,捎帶腳把ANSI轉(zhuǎn)義序列解析也一起抱上了,但還有個情況需要說明。Cygwin核心以及有些命令行程序,能探測到輸出定向至哪里,比如是管道(pipe在UNIX/Linux中十分常見),還是基于pty的終端,或是基于Windows Console的終端。當探測到是基于pty的終端時,Cygwin核心把ANSI轉(zhuǎn)義序列原封不動地傳遞給終端,完全交由終端自行渲染;而探測到是Windows Console終端的時候,就自己先處理一下再交由終端渲染。也就是說,對于基于Windows Console的終端,Cygwin并不清楚它有多強的功能,于是選擇了不信任,自己上!這樣導(dǎo)致即使有的第三方終端模擬器有處理ANSI轉(zhuǎn)義序列的能力,也無法很好地運行Cygwin命令行程序,下文會介紹。
Windows7 conhost中運行cygwin的lsWindows7 conhost中運行cygwin的ls
Windows7 mintty中運行cygwin的lsWindows7 mintty中運行cygwin的ls
如上兩圖對比效果。注意,本文的Cygwin Shell環(huán)境中設(shè)置了匿名alias ls=ls --color,所以不必加--color選項,而cmd解釋器是不知道Cygwin Shell配置情況的,在conhost窗口中輸入命令要加上--color選項才顯示顏色。另外,由于字符集不統(tǒng)一,conhost窗口把ls命令輸出的中文顯示成“?”。

盡管困難重重,Windows上還是誕生了許多優(yōu)秀的第三方終端模擬器,有的還把ssh/串口/ftp客戶端程序,甚至其他常用命令行程序等也一起打包發(fā)行,已經(jīng)不是單純的終端模擬器了。以下僅列舉幾個。

Mintty

Mintty是一款基于pty的開源終端,從putty 0.60版本的代碼分支而來,現(xiàn)今項目地址:https://mintty.,兼容POSIX “pipe”模式,完全支持ANSI轉(zhuǎn)義序列。不同尋常的是,在抱了Cygwin大腿的同時,還調(diào)用了Win32 GUI API,運行不僅依賴Cygwin核心(cygwin1.dll),還依賴一堆Windows的dll(msvcrt.dll、GDI32.dllUSER32.dll、KERNEL32.DLL)等。它不僅是Cygwin的默認終端,也是MSYS、MSYS2等的默認終端,隨各項目的軟件包發(fā)行,與wslbrige配合還能連接到WSL(的命令行程序)。從這可以看出,Mintty和Cygwin關(guān)系密切不一般,官方默認沒毛病。

Mintty的主要功能特性:

  • 兼容xterm,支持DEC公司(VT100就是他家的)終端產(chǎn)品所有屏幕控制功能;
  • 支持字符加粗、斜體、下劃線、閃爍、前后景色等風格;
  • 全面支持Unicode,支持Emoji;
  • 支持256色和真彩色;
  • 支持圖片顯示;
  • 圖形化配置,保存為配置文件.mintty;
  • 靈活的文字復(fù)制粘貼操作;
  • 支持Windows XP至Windows10。

Mintty項目官網(wǎng)列出展示上述功能特性的截圖,還提供了使用手冊,使用手冊也是隨軟件包一起發(fā)行。Cygwin系列(五):Shell命令行初體驗也簡單說了它的工作原理。

Mintty的強大之處無需贅述,但不可避免地存在一個問題——不能很好地和Windows命令行程序配合起來,一方面前文陳述的Windows Console組件和pty的不兼容,另一方面是Windows命令行程序使用的字符集與Mintty所支持的存在不兼容。還有我個人覺得不太爽的,盡管支持通過如tmux、GNU Screen等多路復(fù)用器切換窗口,但Mintty不支持多標簽頁。

ConEmu

ConEmu是一款優(yōu)秀的開源終端,項目地址https://conemu.。它是混合型的,首要支持Windows Console功能,可看作是conhost的增強版本,同時也部分地支持pty,具備ANSI轉(zhuǎn)義序列直接解析能力,總體上是conhost+Mintty的全能選手。

主要功能特性包括:

  • 多標簽頁、多標簽頁、多標簽頁,重要事情說3遍,并且支持多種布局方式;
  • 不同標簽頁獨立配置Task,也就是運行不同的命令行程序,特別是shell,Task支持名字分組和分配快捷鍵;
  • 界面現(xiàn)代化,有標簽頁、快捷菜單、控制臺區(qū)、狀態(tài)欄、滾動條;
  • 支持連接到多種類型命令行程序環(huán)境,Cygwin、msys、WSL都不在話下;
  • 圖形化配置方式,每一部分都支持個性化配置,所有配置項保存到文件ConEmu.xml;
  • 支持集成到其他程序界面中,比如文件管理器Explorer;
  • 支持字符加粗、斜體、下劃線、閃爍、前后景色等風格;
  • 全面支持Unicode,支持ANSI X3.64標準和xterm256色;
  • 附帶字符界面的文本管理器Far Manager及其插件;
  • 能運行在Windows 2000及以上版本的Windows系統(tǒng),開箱即用;

由于前文所述原因,ConEmu與Cygwin命令行程序的配合暫時還不完美,等未來ConEmu完全支持pty,能騙過Cygwin了,ANSI轉(zhuǎn)義序列直接解析能力才有用武之地。為此,ConEmu臨時提供了間接解決辦法——cygwin terminal connector。隨ConEmu打包的conemu-cyg-64.execonemu-cyg-32.exe程序就是一個terminal connector,本身也是個Cygwin程序,依賴cygwin1.dll。ConEmu通過它啟動Cygwin命令行程序,并強迫Cygwin核心關(guān)掉ANSI轉(zhuǎn)義序列處理,原封不動地交給ConEmu,這好比在Cygwin中安插間諜,抓取第一手情報,但仍只是部分地解決了問題,比如顏色顯示就存在不一致。

ConEmu官方提供了一個在ConEmu內(nèi)連接Cygwin bash的Task配置示例。

1
2
3
set "PATH=C:\cygwin64\bin;%PATH%" & 
%ConEmuBaseDirShort%\conemu-cyg-64.exe /usr/bin/bash.exe --login -i
-new_console:p:C:"C:\cygwin64\Cygwin.ico"

解釋如下:

  • C:\cygwin64\bin加到Windows PATH環(huán)境變量是為了讓conemu-cyg-64.exe準確找到Cygwin核心(cygwin1.dll),明確Cygwin根路徑;
  • /usr/bin/bash.exe --login -i是指定ConEmu要連接的命令行程序及其參數(shù),此處是連接到Cygwin的bash,也可以配置為其他;
  • 最后一行是ConEmu特有的選項開關(guān),選項間用”:”隔開,-new_console含義是打開新標簽頁,p是指定pty模式,C:\cygwin64\Cygwin.ico是指定標簽頁使用的圖標文件。

更詳細解釋及其他有效配置見官方文檔 https://conemu./en/CygwinMsysConnector.html。ConEmu還打包了msys、msys2的terminal connector——conemu-msys-32.execonemu-msys2-32/64.exe;給WSL的terminal connector和Cygwin的一樣,也是需要與wslbrige配合起來,官網(wǎng)也提供了連接到msys、msys2、WSL的Task配置示例。搭配一個Windows的ssh客戶端程序,配置好Task,也能將ConEmu連接到遠程的ssh server。

配置Task較多,分組的作用就體現(xiàn)出來了。比如把Windows中的cmd、Power Shell、python shell、ipython都分到Windows組,在Cygwin中有bash、zsh、fish、ipython等等,可以歸并到Cygwin組,如果同時還用msys、WSL什么的,也可以相應(yīng)增加分組。這樣可以做到每種環(huán)境獨立劃分一個組,不至于同名的程序難以區(qū)分,界面上也干凈清爽。

如圖有多個分組,已同時打開4個不同標簽頁,可用ctrl+TAB鍵順序切換或ctrl+數(shù)字鍵任意跳轉(zhuǎn)。
ConEmu界面ConEmu界面

最后,ConEmu真香!

其他

  • cmder是一款默認配置十分漂亮的開源終端,項目地址:https://。cmder是基于ConEmu而開發(fā)的,它分為mini版和full版,mini版基本就是一套ConEmu了,full版就是把git bash for Windows也打包在一起。
  • console2、consoleZ都是基于Windows Console的開源終端,支持多標簽頁,是conhost的包裝。console2項目地址 https:///projects/console,由于長久未更新,才有了分支consoleZ,后者項目地址https://github.com/cbucher/console,支持連接到cmd/Power Shell、Cygwin、msys(2),界面與Mintty極其相似。
  • git bash for Windows是git官方給Windows平臺做的git打包,可以看作是msys(2)的子集,使用的終端是Mintty,另外把整套git和少數(shù)UNIX常用命令行程序打包在一起。
  • Xshell、MobaXterm均為商業(yè)產(chǎn)品,界面華麗,不是單純的終端了,它們把telnet、ssh、ftp這些常用客戶端程序也打包進來了,MobaXterm甚至把x server都打包進來。

0x03 總結(jié)

歷史發(fā)展造成了UNIX與Windows平臺互不兼容的命令行生態(tài),UNIX/Linux的開放性使得第三方終端繁榮發(fā)展,Windows的封閉性和對命令行的忽視給第三方終端增加重重困難,盡管如此還是誕生了優(yōu)秀的終端模擬器。經(jīng)過使用,本人強烈安利ConEmu替代上述所有。

填補Windows Console和pty的差異性,不只是Cygwin這一條”重量級”解決方案,敬請期待下一篇繼續(xù)深度扒終端。

參考

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多