本文共4300余字,預(yù)計(jì)閱讀時(shí)間15分鐘,本文同步發(fā)布于知乎(賬號silaoA)和微信公眾號平臺(賬號偽碼人)。
前一篇文章Cygwin系列(四):一步一步搭建Cygwin最小系統(tǒng)中已建立了最小系統(tǒng)環(huán)境,本篇將初步體驗(yàn)Cygwin的Shell命令行。
利用setup
安裝完最小系統(tǒng)后,桌面上建立了一個(gè)名為“Cygwin Terminal”的快捷方式。
桌面上Cygwin Terminal快捷方式
雙擊運(yùn)行,彈出一個(gè)黑框框,初次運(yùn)行還會自動幫用戶做一些配置工作,如建立用戶目錄等。最后,打印一個(gè)形式如“xxx@yyy ~ $”的提示符,緊跟著是閃爍的光標(biāo),等待用戶輸入。如果直接按回車,黑框框里就換行繼續(xù)打印出同樣的提示符,同樣跟著是閃爍的光標(biāo),繼續(xù)等待用戶輸入。
那,可以做點(diǎn)什么呢?換句話說,我們能運(yùn)行什么命令?先試試ls /
,本人的輸出結(jié)果如下圖,注意到本人因做了額外配置,因此顯示內(nèi)容、顏色與你的可能不同,注意“s”和“/”之間有空格隔開。
命令“l(fā)s /”的結(jié)果
再來解釋這個(gè)命令,ls
是命令名稱,是list的簡寫,用于列出指定路徑下的文件,而“/”就是指定的“路徑”。那么,“/”指的哪個(gè)路徑?如果稍稍留意輸出結(jié)果,可以推測出“/”就是指Cygwin安裝的頂層路徑。好像沒什么稀奇的,Windows下用Explorer也看看到指定路徑下的文件,而且更直觀。
不著急,再繼續(xù),試試help
,輸出如下,結(jié)果比較長,截圖只有一部分。這個(gè)命令貌似是告訴用戶一些命令的用法。
命令“help”的結(jié)果
初次體會到此結(jié)束,接下來并不想要你在黑框框里盲目亂敲,讓我們暫且開啟高空俯視視角,避免迷失在暗黑森林。
好奇心驅(qū)使我去了解雙擊“Cygwin Terminal”快捷方式后,Windows幫我做了些什么。查看快捷方式的屬性,其中“目標(biāo)”字段的值為“D:\Cygwin64\bin\mintty.exe -e /bin/bash –login -i”,從這里可以推斷,快捷方式實(shí)際運(yùn)行的是mintty.exe
,它就在Cygwin安裝目錄(D:\Cygwin64)的bin
子目錄中,那么mintty
是什么?后邊的“-e /bin/bash –login -i”又是什么意思?
查詢mintty官網(wǎng)上有文檔介紹,mintty
是用于Cygwin、MSYS、Msys2等項(xiàng)目的“終端模擬器(Terminal Emulator)”,顧名思義,它就是用來模擬終端的,但是終端自身僅具有基本輸入輸出能力,并不會執(zhí)行程序指令。
再接著看,看到下面這張圖,mintty
的help輸出中有一行“-e –exec Treat remaining arguments as the command to execute”,也就是“/bin/bash –login -i”是mintty
啟動后要執(zhí)行的命令,這是要mintty
啟動bash.exe
的節(jié)奏,還順帶傳遞了–login和-i選項(xiàng),再一查“bash”,大名鼎鼎的Bourne Again Shell
。再結(jié)合mintty
的help
輸出的頭兩行“Start a new session running the specified program or user’s shell”,也就是說mintty啟動的時(shí)候,會開啟一個(gè)終端會話運(yùn)行指定的程序或用戶Shell,上述“/bin/bash –login -i”正是“指定的程序”。 更多詳情,mintty官網(wǎng)給了詳細(xì)的手冊頁。
mintty的help信息(圖片來源:https://mintty.github.io)
進(jìn)一步,打開Windows任務(wù)管理器,看到一個(gè)“應(yīng)用”Terminal和一個(gè)“后臺進(jìn)程”bash.exe,右鍵Terminal,轉(zhuǎn)到詳細(xì)信息,正是mintty.exe。
查看到mintty和bash進(jìn)程
至此,可以初步確定,雙擊快捷方式實(shí)質(zhì)是啟動了mintty,而mintty又啟動了后臺進(jìn)程bash,我們看到的前臺窗口是mintty,而幕后則有bash在干活。
經(jīng)過一番操作(此處省略一萬字……),了解到終端、終端模擬器、Shell的概念,可以總結(jié)如下:
①終端自身并不執(zhí)行用戶輸入的命令,它只是負(fù)責(zé)把輸入的內(nèi)容傳給系統(tǒng),并把結(jié)果呈現(xiàn)在窗口上給用戶看;
②終端模擬器是一個(gè)模擬終端的圖形界面軟件,mintty就是一個(gè)終端模擬器實(shí)例;
③Shell是負(fù)責(zé)解釋執(zhí)行用戶命令的解釋器,bash就是一個(gè)Shell實(shí)例,它是由mintty在后臺啟動的。
從操作關(guān)系角度,可以簡要繪制如下示意圖,其中Cygwin核心是更深層幕后工作者,為mintty、bash的運(yùn)行提供環(huán)境支撐。
用戶、mintty、bash操作關(guān)系示意
好了,現(xiàn)在理清楚了,在mintty
輸入的內(nèi)容實(shí)際都交給了Shell(bash)在處理,輸入的內(nèi)容即為“命令”。俗話說“沒有規(guī)矩不成方圓”,bash
自有其一套語法規(guī)則,不合規(guī)則的輸入內(nèi)容不能視作合法命令,Shell(bash)無法處理。
每條命令大體上遵循“<命令名稱> <選項(xiàng)> <選項(xiàng)值> <參數(shù)>”的形式,命令名稱(command)、選項(xiàng)(option)、選項(xiàng)值(value)、參數(shù)(argument)之間用空格隔開。除了命令名稱,其他部分都不是必需的,比如在本文最開頭執(zhí)行的ls /
,其中ls
是命令名稱,/
是參數(shù),help
就僅包含命令名稱,mintty --help
只包含命令名稱和選項(xiàng),沒有選項(xiàng)值和參數(shù)。
計(jì)算機(jī)發(fā)明之初,存儲器是很稀有的資源,為了盡量減少存儲空間,也為了方便用戶記憶,命令名稱都是單詞簡寫,十分簡潔,這個(gè)傳統(tǒng)基本上被保留下來。
命令名稱描述要做什么(Do What),這個(gè)好理解,參數(shù)描述的是作用對象(to Whom),也比較好理解,而選項(xiàng)和選項(xiàng)值則具體描述怎么做(How to Do),這就比較復(fù)雜了。事實(shí)上,各個(gè)命令描述最多的地方就是選項(xiàng)和選項(xiàng)值。
選項(xiàng)有單個(gè)連字符(-)與字母組成的短選項(xiàng)風(fēng)格(UNIX風(fēng)格)和兩個(gè)連字符(–)與單詞組成的長選項(xiàng)風(fēng)格(GNU風(fēng)格),很多命令兩者都支持,而且部分短選項(xiàng)和長選項(xiàng)等效,還有少數(shù)命令支持“+”與字母組成的選項(xiàng),甚至與這些風(fēng)格都不符的選項(xiàng)。
大部分命令都有“-v”和“-h”這兩個(gè)選項(xiàng),或等價(jià)的“–version”和“–help”,用于顯示版本信息和幫助信息。熟悉應(yīng)用程序,最主要地就是熟悉不同選項(xiàng)和不同參數(shù)配合作用,并加以掌握。對某個(gè)程序命令完全不了解或者是忘記了,都可以嘗試“-h”、“–help”、“-v”、“–version”選項(xiàng)去了解。
Shell能識別的命令大致分為3類:
①內(nèi)建(built-in)命令,僅與Shell自身有關(guān),不同的Shell(如sh、bash、zsh、fish等)支持的內(nèi)建命令;
②用戶定義函數(shù)(function)、別名(alias)等,用戶可自定義一些Shell函數(shù),給命名設(shè)置別名等;
③外部命令,額外安裝的可執(zhí)行程序越多,可供執(zhí)行的外部命令就越多,比如ls就是外部命令。
要查詢某個(gè)命令屬于哪種,執(zhí)行type -a <命令名稱>
即可;要看當(dāng)前Shell支持哪些內(nèi)建命令,執(zhí)行help
即可,其中type
、help
就是bash
等Shell都會提供的內(nèi)建命令。在剛安裝完Cygwin最小系統(tǒng)時(shí),bin
子目錄下大量可執(zhí)行文件,除去一些DLL文件,其余都是Shell外部命令。
文件都是存放在具體某個(gè)路徑下的,Shell在工作的時(shí)候也是處在某個(gè)路徑下,要查詢當(dāng)前工作路徑(current working directory)是什么,可以通過內(nèi)建命令pwd
打印出來,內(nèi)建命令cd <路徑>
可以切換工作路徑。
Shell剛啟動的時(shí)候,默認(rèn)切換到當(dāng)前用戶目錄作為初始工作路徑,前文提到的提示符中,~
就是當(dāng)前用戶目錄,試下pwd
如圖,結(jié)果為/home/<用戶名>
。其中,home
是Cygwin安裝目錄下的子目錄,<用戶名>
是登錄當(dāng)前Shell的賬號,在Cygwin中登錄當(dāng)前Shell的賬號就是登錄到Windows系統(tǒng)的用戶名,這個(gè)子目錄是首次啟動Shell時(shí)自動建立的。
“~”指示當(dāng)前用戶目錄
為什么要強(qiáng)調(diào)“當(dāng)前”?因?yàn)閁NIX/Linux是真正的多用戶系統(tǒng),允許多個(gè)用戶同時(shí)登錄到系統(tǒng)中取得使用權(quán),系統(tǒng)給每個(gè)用戶在/home
目錄下建立各自的用戶目錄,這樣每個(gè)用戶的環(huán)境彼此隔離、互不干擾。Windows是號稱多用戶系統(tǒng),雖然也給每個(gè)用戶建立各自的用戶目錄,在C:\Users
下,但是Windows一次只允許一個(gè)用戶登錄。
以上洋洋灑灑長篇大論,除了開頭演示ls /
、help
和中間穿插介紹的type
、cd
、pwd
,就沒介紹幾個(gè)命令用法。本節(jié)也只打算介紹幾個(gè)關(guān)鍵命令,記住這幾個(gè),就可以去從零了解各個(gè)命令用法。
help
是Shell內(nèi)建命令,可以查看各個(gè)內(nèi)建命令的用法。如果不帶參數(shù),help
輸出當(dāng)前Shell支持的所有內(nèi)建命令;如果帶參數(shù),help <參數(shù)1> <參數(shù)2> ···
則按參數(shù)逐個(gè)嘗試查找?guī)椭黝},通常所有參數(shù)應(yīng)當(dāng)為內(nèi)建命令或者能匹配內(nèi)建命令的模式,比如h*匹配所有以h開頭的內(nèi)建命令:help
、history
。
“help help”結(jié)果
對于絕大多數(shù)外部命令,都支持至少“-h”和“–help”選項(xiàng)之一,用于顯示該命令的用法,即使“-h”可能用作他途,但“–help”絕對是顯示用法。
“l(fā)s --help”結(jié)果
也有少數(shù)命令不支持“-h”或“–help”選項(xiàng),而是在沒有任何選項(xiàng)參數(shù)或者出錯的時(shí)候顯示用法。
man
是POSIX規(guī)定的幫助手冊程序,是mannual的簡寫。軟件包中除了程序本身,還帶了大量用戶文檔,在UNIX/Linux系統(tǒng)中,手冊頁是最常見的用戶文檔之一,man
手冊頁用特殊的格式寫成并壓縮,通過man命令瀏覽。系統(tǒng)安裝的軟件包手冊頁通常在/usr/share/man/
目錄之下,按照章節(jié)分門別類地放在man1~man8子目錄中。
參照上面的說明,試試man --help
,如下圖man
支持的選項(xiàng)很多,<章節(jié)>參數(shù)可以是1~8,指定man查找的章節(jié)。一般使用場景中不需要任何選項(xiàng),直接man <主題>
即可,man
從1~8所有章節(jié)去查找,主題不限于命令名稱,還可以是系統(tǒng)調(diào)用、函數(shù)庫等。
“man --help”結(jié)果
在man查看手冊頁時(shí),空格鍵向下翻頁,PgUp/PgDn鍵向上/下翻頁,↑/↓鍵向上/下移動一行,g/G跳轉(zhuǎn)到頁面頂部/底部,q退出,h查看幫助操作。更多詳情,試試“man man”。
用戶文檔除了man
手冊頁,還有info格式的手冊頁,由GNU項(xiàng)目引入,通過info
(information的縮寫)命令瀏覽,一般UNIX/Linux系統(tǒng)同時(shí)支持man
和info
兩種風(fēng)格的手冊頁。
Info手冊頁按照節(jié)點(diǎn)(node)組織,每個(gè)手冊頁文件是一個(gè)節(jié)點(diǎn),手冊頁內(nèi)支持鏈接到其他節(jié)點(diǎn),如此組織猶如一張網(wǎng),和網(wǎng)頁類似。Info手冊頁一般存放在/usr/share/info
目錄下,其中dir
文件是Top節(jié)點(diǎn),相當(dāng)于網(wǎng)站中的index首頁。
老規(guī)矩,info --help
試試怎么用,如圖,info
也支持較多選項(xiàng),給出的例子中,直接info <主題>
,和man
類似。不加主題參數(shù)時(shí),info
默認(rèn)打開Top節(jié)點(diǎn)。
“info --help”結(jié)果
在info瀏覽手冊頁時(shí),空格向下翻頁,PgUp/PgDn鍵向上/下翻頁,↑/↓鍵向上/下移動一行,b/e跳轉(zhuǎn)至當(dāng)前節(jié)點(diǎn)頁首(begin)/頁末(end),q退出,Enter跟蹤鏈接,p/n/u跳轉(zhuǎn)至與當(dāng)前節(jié)點(diǎn)關(guān)聯(lián)的前一個(gè)(previous)/后一個(gè)(next)/上一級(up)節(jié)點(diǎn),l回退至上次(last)頁面,m/g跳轉(zhuǎn)至本節(jié)點(diǎn)內(nèi)菜單(menu)項(xiàng),Ctrl-g取消當(dāng)前要執(zhí)行的動作。更多詳情,試試info info
命令。
--help
選項(xiàng)、man
、info
命令,配合網(wǎng)上應(yīng)用案例,也能摸清個(gè)大概了。
聯(lián)系客服