從Windows到Linux(三):擁抱命令行

一直很困惑很多人都說在Linux上命令行是極有用處和極好用的。對於前者,本人表示贊同,的確在Linux上離開命令行簡直沒法活了。但是好用就要打個問號了。首先,對於剛剛開始使用的人根本就不知道要使用什麼命令。隨便從網上找幾個apt-get之類的命令,用了也是知其然不知其所以然的。然後於是乎到網上搜索一番,找到一大堆的常用命令。然而似乎也並沒有什麼用。就拿ls命令來說,對於日常工作似乎並沒有什麼實際用處。類似的工作,用圖形界面不是更好麼。


但是不管怎麼說,命令行就在那裏,不管我們懂不懂,喜不喜歡,他就在哪裏。一番回憶和搜索之後,本人似乎這兒題目似乎有了一些解。


一、終端


要玩轉命令行,讓一切瞭然與心。需要先清楚一些概念。


首先是tty。玩過Linux內核的人都知道tty,知道tty是一種內核文件。但是tty的來源以及定義卻未必是人人都清楚的。


這裏首先說終端和控制檯。早期計算機是由多人共享使用的。每個人使用一種設備和主機建立鏈接,然後使用主機的資源。這種設備就被稱作終端。它用戶輸入,並將其發送給主機,並顯示主機返回計算結果。因爲終端是給多人使用的,是在主機啓動之後才和主機建立鏈接的,所以需要另外一種設備可以完全控制主機。這種設備就叫控制檯。控制檯是直接連接到主機的,屬於主機的一部分。開機的時候,主機會把一些信息打印到控制檯上,但是不會打印到終端。一臺主機可以有很多終端,但是隻會有一個控制檯。後來,隨着PC的出現,人們使用電腦的方式出現了變化。控制檯和終端演化成了軟件的概念,他們又被稱作虛擬控制檯和虛擬終端。


現在Linux還提供5個基於命令行的虛擬終端(分別通過Ctrl+Alt +F2~F6進行切換),一個圖形虛擬終端(Ctrl+Alt+F7進行切換),以及一個虛擬控制檯(Ctrl+Alt+F1)。這就是在模擬當初多人使用同一臺主機的場景。不過在Linux中這個控制檯和其他終端之間的區別已經非常模糊了。比如在第2個虛擬終端執行以下命令:


        echo "hello,world" > /dev/console


“hello world”會被顯示在當前屏幕


最早出現的終端設備,是由TeleType生產的,據說類似於“電傳打字機”。不過本人也沒見過電傳打字機,也只能臆想一下了。這些設備也就是稱作tty,大約是teletypes或teletypewriter的縮寫。後來tty也就泛指各種終端設備了。打開./dev會看到遠超7個的tty文件(tty0~tty63),個人理解對於PC是沒什麼用的,因爲一般情況不會有那麼多終端鏈接到主機。

wKiom1eseq7RXBUiAAGLH0TcaCQ452.png-wh_50


在Ubuntu下使用命令行有兩種操作方式。一種是使用Ctrl+Alt+F1~F6在各個終端之間切換。另外一種是在圖形界面環境下打開一個命令行窗口。在這兩種方式有區別嗎?當然有。在圖形界面下打開的命令行窗口不是終端,而是叫做終端模擬器,也叫僞終端。僞終端的工作方式是這樣的:

wKiom1esewCSOkMFAABYgYjuJ68311.png-wh_50


可以把僞終端從設備看成是傳統的中終端設備,而把僞終端主設備看作數據讀寫的接口,就可以理解了爲什麼僞終端用來提供圖形界面或網絡環境下的終端模擬了。


這類可以看出×nix內核的靈活性了。不用另起爐竈,只需增加兩種不同的設備文件就實現了遠程終端。


話說多了。那究竟使用那種方式好呢?個人認爲是僞終端比較好了。首先,使用僞終端的同時還可以使用圖形界面。無論好壞,圖形界面在某些情況下還是有優勢的,不能全盤否定,哪怕是在Linux上。其次,僞終端對於個人用戶來說在某種程度上可以說沒有個數限制,想開多少個就開多少個,個人認爲這個東西是多多益善。這裏我們終於不用糾結或者內心愧疚在Linux下沒有使用 純命令行界面了。


現在常見的虛擬終端軟件有:xterm、rxvt、lxterminal、terminal


二、命令行,爲什麼?


說了半天終端的原理和歷史,但是終端對於使用者而言只是一個黑黑的屏幕,和Windows上的命令行看起來差不多。並不能體現出Linux命令行的強大易用。就目前而言,也只是搞清楚了不必拋棄圖形界面,因爲在圖形接界面環境下命令行窗口想有多少個就有多少個。


思來想去,個人認爲Linux命令行之所以強大和這樣一些東西有關:終端、Shell、標準輸入輸出、管道、多進程架構、文化(又是文化……)。


Linux中每個終端有一個輸入隊列和輸出隊列,每個進程會有三個流(stdin、stdout、stderr)。當從終端運行一個程序時,系統將進程的標準輸入輸出流連接到終端的輸入輸出隊列。如下圖:

wKioL1ese0-T4o5gAAA_MTSgTMI355.png-wh_50


然後鍵盤輸入就變成了進程標準輸入(stdin),屏幕則接受進程標準輸出(stderr)和標準錯誤(stderr)。這就是Linux中命令行的工作方式,也叫終端IO。這種工作方式需要進程和終端之間的配合,以及程序對標準IO進行處理。沒有什麼特別神奇的地方,Windows中也是一樣,進程可以通過標準輸入從命令行讀取數據,然後通過標準輸出將結果輸出給命令行。但是問題是Windows有多少程序使用標準輸入輸出呢?恐怕大多數程序都沒有進行這方面的處理吧。


當然程序對標準輸入輸出進行處理只是命令行的基礎,還談不上好用和強大。Linux中命令行的第二種方式是使用輸入輸出重定向,也就是管道。當執行一個進程,進程的輸出被重定向到另一個進程作爲其輸入。如下圖:

wKiom1ese73BT2gkAABGPsG3GgY426.png-wh_50


管道將命令ls的輸出送給wc命令進行統計


其實這個也不是特別神奇,因爲在Windows上也有管道,也一樣可以進行輸出重定向。


要命的東西是多進程。在Linux上,進程相對Windows來說比較輕量級。所以Linux程序多采用多進程架構,進程間通過管道進行通信。一個任務往往是由多個進程之間協同完成的。這個時候標準IO和管道就特別有用了。而在Windows上進程比較重,一般的程序都不採用多進程,而是在必要的時候使用多線程。也就是說在Windows上通常不進行進程間協作,而是每個進程獨立提供所有功能和獨立完成所有任務。而更有甚者的是很多Windows程序根本不使用標準輸入輸出,因爲不需要和其他進程協作。


這是兩種不同的設計理念,無所謂好壞。但是多進程+管道的模式的確是能在命令行環境下發揮出強大的爲例。而在計算機性能不是那麼好的當年,單進程/多線程架構在用戶體驗上也似乎能夠提供更好的響應速度(其實爲了提高圖形界面的響應速度,Windows甚至將GUI放在內核態,也是蠻拼的)。


標準IO+管道+多進程的好處有很多,個人認爲還有一個比較重要的就是軟件複用。一個軟件只要定義好了標準IO就可以很容易的爲其他軟件提供服務了,這麼一來複用他人的軟件就比較容易了。相對而言圖形界面就沒有這個優勢。基於標準IO的軟件複用的容易程度提升了大家對軟件複用的共識,而軟件複用的共識又進一步增強了軟件的複用度,進而形成了文化。而這一切都是基於命令行的,在這種形式下命令行想不強大都不行啊……


個人覺得,這個多進程架構+管道+終端的模式是導致Linux上圖形界面用戶體驗不佳的重要原因之一。不是因爲技術,而是大家都把注意力放在了標準IO的處理以及軟件複用上,對圖形界面的關注度根本不夠。


當然這一切看起來非常美好的架構最後是要依靠Shell來實現的,比如前文的ls| wc -l,就是Shell負責組組合起來的。Shell的衍生品Shell編程,更是讓命令行如虎添翼,成了Linux上編程的必學課程。


三、基礎命令


總算是感覺連猜帶蒙的自圓其說了爲什麼Linux上命令行強大無比了,無論怎樣也要求個下心安理得先。


在使用Linux的過程中關於命令行,除了前面討論的外,本人的有兩大困惑。一是如果要完成一件事該區使用什麼命令,去哪裏能夠找到?二是這些命令的名字都好奇怪啊,完全看不懂

關於後者,下面是本人一番搜索後的結果:

命令

說明

sudo

是系統管理員讓普通用戶執行一些root命令的程序。基本可以理解成在要執行的命令前加上sudo就表示以root權限執行該命令。這裏設計到另外一個命令:su。su可以用來臨時切換到root用戶,su有個安全隱患,所以人們在su的基礎上發明了sudo。相對來說sudo的優勢在於:需要授權(權限不是無限的),以及使用時不需要知道root賬戶的密碼。

英文:su->switch user

apt-get

適用於使用deb包管理系統的Linux發行版本。用於從互聯網的軟件倉庫中搜索、獲取、安裝、卸載軟件。

英文:Advance Package Tool

dpkg

dpkg本身是一個底層工具,前面的apt就是基於dpkg從遠程獲取和安裝軟件包的

英文:debian package

cd

切換當前目錄

英文: change directory

pwd

打印當前工作目錄

英文:Print Working Directory

man

命令幫助文檔。還有就是無論什麼其他命令都可以忘記,但是這個不能忘。

英文:manual

ls

列出目錄中的文件

英文:list

shutdown

關機

logout

註銷

tree

顯示文件和目錄由根目錄開始的樹形結構

mkdir

創建目錄

英文:make ddirectory

rm

刪除目錄或文件

英文:remove

cp

複製目錄或文件

英文:copy

find

搜索文件或目錄

chmod

設置文件權限

英文:change mode

fg

將程序切換到前臺運行

pg

將程序切換到後臺運行

jobs

顯示所有在後臺運行的應用

ps

ps

進程狀態

英文:process state


可能是爲了滿足在命令行中輸入要儘量精簡的需求,這些命令大量用了縮寫。結果就是初次使用的時候一頭霧水啊。有些縮寫完全具有誤導性,比如pwd,看起來更像是和設置密碼有關的命令。看來還真是沒事要多用man看看命令幫組文檔。


另外這裏有個使用心得也是關於man的。執行命令:


man [軟件名稱]


能夠獲得該軟件的相關命令幫組,畢竟強大的命令行文化需要有強大的命令行工具和足夠的文檔,否則拿到一個新程序鬼才知道該怎麼去用呢。

wKioL1esfC6yvIb-AAEWRdP4qYA750.png-wh_50


四、快捷鍵


命令行的確強大,但是如果沒有一些快捷鍵根本抖不起來。下面是本人蒐集的一些常用快捷鍵:

快捷鍵 說明

↑ 或 Ctrl+p

顯示上一條命令

↓ 或 Ctrl+n

顯示下一條命令

→ 或 Ctrl+f

光標向右移動一個字符

← 或 Ctrl+b

光標向左移動一個字符

Alt+f

光標向右移動一個單詞

Alt+b

光標向左移動一個單詞

Ctrl+r

逆向搜索包含輸入字符串的命令

Ctrl+s

正向搜索包含輸入字體串的命令

Ctrl+a

光標移動到開頭

Ctrl+e

光標移動到結尾

Ctrl+l

清屏

Ctrl+u

剪切光標所在處之前的所有字符 (不包括自身)

Ctrl+k

剪切光標所在處之後的所有字符 (包括自身)

Ctrl+w

剪切光標所在處之前的一個詞 (以空格、標點等爲分隔符)

Ctrl+y

粘貼

Alt+u

將光標所在處的單詞轉爲大寫 (從光標處到詞的結尾)

Ctrl+c

中斷命令

Ctril+z

掛起當前應用


五、更多


前面提到在圖形界面環境下可以開多個命令行窗口輕鬆實現多任務。那麼非圖形界面下如何執行多任務呢?這個問題一度困惑本人,導致不停的開很多個命令行窗口。在研究命令的時候才發現命令行模式下也是支持多任務的。


通常來說從命令行啓動gedit,命令行會直到gedit退出後才能執行下一個命令。如圖:

wKiom1esfGPxYzrbAAA__uEvEPA025.png-wh_50


但是如果我們在執行gedit的時候在後面加一個“&”那就情況不同了

wKioL1esfIDghL76AABL3e05tgI282.png-wh_50


哈哈,光標在動。可以無憂無慮的執行下一個任務了。這個就是命令行模式下的多任務。具體設計到的指令有:fg、bg、jobs、ps、kill和快捷鍵Ctrl+c、Ctrl+z。


Linux命令行果然強大。


六、結束語


當年讀關於Linux內核的書的時候看到管道相關的章節淺嘗則止草草掠過。因爲在Windows下這個東西似乎無足輕重,畢竟沒什麼人用。但是這次結合命令行以及多進程體系結構看起來,他彷彿是Linux系統的血管了,幾乎無處不在把各個程序串聯起來。


另外關於命令行這個東西的學習。其實對於技術人員本身而言,大多都是不排斥命令行的。但是常見的Windows開發人員對命令行非常不感冒,究其原因就是沒能瞭解這背後的一整套邏輯:終端+標準IO+管道+多進程。而一旦瞭解這些邏輯(文化)之後,很容易的就會欣賞這種方式,進而擁抱之。這其實也是一種體驗。可惜的是,多年以來本人從未沒有看到有論述這方面內容的書籍文章(也許是太低端了,談Linux必談內核?)。大多都是以一副普世價值的姿勢教導命令行的強大之處,缺少言傳身教的耳濡目染,可惜偏偏在感性上命令行是遠不如圖形界面強大和方便的(在Windows上也的確是如此)。


所以下面本人打算開始探索軟件包的管理和程序的執行。這個比搞清楚樹形目錄文件系統對於使用Linux顯得更總要。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章