什麼是shell
shell的本意是“殼”的意思,其實已經很形象地說明了shell在Linux系統中的作用。shell就是圍繞在Linux內核之外的一個“殼”程序,用戶在操作系統上完成的所有任務都是通過shell與Linux系統內核的交互來實現的。我們應該熟悉DOS系統中command.com程序,shell的功能與此類似,但是shell的功能更加強大,更加好用。
各種操作系統都有自己的shell。以DOS為例,它的shell就是command.com程序。DOS下還出現了很多第三方命令解釋程序,例如4DOS、NDOS等,這些命令解釋程序完全可以取代標准的command.com程序。同樣,Linux下除了默認的Bourne again shell(bash),還有很多其他的shell,例如C shell(csh)、Korn shell(ksh)、Bourne shell(sh)和Tenex C shell(tcsh)等。每個版本的shell功能基本相同,但各有千秋,現在的Linux系統發行版一般都以bash作為默認的shell。
shell本身是一個C語言編寫的程序,是用戶和操作系統內核之間通信的橋梁。shell既是一種命令解釋程序,又是一種功能強大的解釋型程序設計語言。作為命令解釋程序,shell解釋用戶輸入的命令,然後提交到內核處理,最後把結果返回給用戶。
為了加快命令的運行,同時更有效地定制shell程序,shell中定義了一些內置的命令,一般我們把shell自身解釋執行的命令稱為內置命令,例如下面我們將要講到的cd、pwd、exit和echo等命令,都是屬於bash的內置命令。當用戶登錄系統後,shell以及內置命令就被系統載入到內存,並且一直運行,直到用戶退出系統為止。除了內置命令,Linux系統上還有很多可執行文件。可執行文件類似於Windows下的.exe文件,這些可執行文件也可以作為shell命令來執行。其實Linux上很多命令都不是shell的內置命令,例如ls就是一個可執行文件,存放在/bin/ls中。這些命令與shell內置命令不同,只有當它們被調用時,才由系統裝入內存執行。
當用戶登錄系統後,如果是登錄字符界面,將出現shell命令提示符。“#”表示登錄的用戶是系統超級用戶,“*”表示登錄到系統的是普通用戶。shell執行命令解釋的具體過程為:用戶在命令行輸入命令提交後,shell程序首先檢測是否為內置命令,如果是,就通過shell內部的解釋器將命令解釋為系統調用,然後提交給內核執行;如果不是shell內置的命令,那麼shell會按照用戶給出的路徑或者根據系統環境變量的配置信息在硬盤尋找對應的命令,然後將其調入內存,最後再將其解釋為系統調用,提交給內核執行。
最後shell還是強大的解釋型程序設計語言,它定義了各種選項和變量,幾乎支持高級程序語言的所有程序結構,例如變量、函數、表達式和循環等。利用shell可以編寫shell腳本程序,類似於Windows/DOS下的批處理文件,但是shell功能更加完善,更加強大。
4.1.2 shell命令的語法分析
Linux下的各種shell的主要區別在於命令行的語法。對於一些普通的命令,各個shell版本的語法基本相同,只有在編寫一個shell腳本或者使用一些shell高級特性的時候,各個版本shell的差異才會顯示出來。
shell語法分析是指shell的對命令的掃描處理過程,也就是把命令或者用戶輸入的內容分解成要處理的各個部分的操作。在Linux系統下,shell語法分析包含很多的內容,例如重定向、文件名擴展和管道等。
本節我們以bash為例,介紹以下shell命令的語法分析。
1.shell的命令格式
用戶登錄系統後,shell命令行啟動。shell遵循一定的語法格式將用戶輸入的命令進行分析解釋並傳遞給系統內核。shell命令的一般格式為:
command [options] [arguments]
根據習慣,我們一般把具有以上格式的字符串稱為命令行。命令行是用戶與shell之間對話的基本單位。
— command:表示命令的名稱。
— options:表示命令的選項。
— arguments:表示命令的參數。
在命令行中,選項是包含一個或多個字母的代碼,主要用於改變命令的執行方式。一般在選項前面有一個“-”符號,用於區別參數。例如:
[root@WEBServer ~]#ls -a
ls命令加上-a選項後,列出當前目錄下的所有文件(包含隱藏文件)。如果ls不加“-a”選項,則僅僅顯示當前目錄下的文件名和目錄(不顯示隱藏文件)。
一般命令都有很多選項,可以單獨列出它們,也可以在“-”後面把需要的選項都列出來,例如,
ls –a –l
也可以寫成:
ls –al
很多命令都可以接受參數。參數就是在選項後面緊跟的一個或多個字符串,這些字符串指定了命令的操作對象,如文件或者目錄。例如,要顯示/etc目錄下的所有文件及信息,可用以下命令:
[root@WEBServer ~]#ls –al /etc
特殊情況下,有些命令可以不帶參數,例如ls命令,而有些必須帶參數。當參數不夠時,shell就會給出錯誤提示。例如,mv命令至少需要兩個參數。
[root@WEBServer ~]#mv mylinux1.txt mylinux.txt
在shell的一個命令行中,還可以輸入多個命令,用分號將各個命令分開,例如:
[root@WEBServer ~]#ls –al;cp mylinux1.txt mylinux2.txt
相反也可以在多行中輸入一個命令,用“\”將一個命令持續到下一行:
[root@WEBServer ~]#cp –i \
>mylinux1.txt \
> mylinux2.txt
2.shell的通配符
通配符主要是為了方便用戶對文件或者目錄的描述,例如用戶僅僅需要以“.sh”結尾的文件時,使用通配符就能很方便地實現。各個版本的shell都有通配符,這些通配符是一些特殊的字符,用戶可以在命令行的參數中使用這些字符,進行文件名或者路徑名的匹配。shell將把與命令行中指定的匹配規則符合的所有文件名或者路徑名作為命令的參數,然後執行這個命令。
bash中常用的通配符有“*”、“?”、“[]”。
(1)“*”——匹配任意一個或多個字符
例如:
[root@WEBServer ~]#ls *.txt
這個命令是列出當前目錄中所有以“.txt”結尾的文件(除去以“.”開頭的文件)。
[root@WEBServer ~]#cp doc/* /opt