1、神奇高效的Linux命令行

一、爲什麼要學linux命令

Linux是由命令行組成的操作系統,精髓在命令行,無論圖形界面發展到什麼水平,命令行方式的操作永遠是不會變的。Linux命令有許多強大的功能:從簡單的磁盤操作、文件存取,到進行復雜的多媒體圖像和流媒體文件的製作,都離不開命令行。雖然Linux也有桌面系統,但是X-window也只是運行在命令行模式下的一個應用程序。

因此,可以說命令是學習Linux系統的基礎,在很大程度上學習Linux就是學習命令,很多Linux高手其實都是玩兒命令很熟練的人。

也許對於剛剛從Windows系統進入Linux學習的初學者來說,立刻進入枯燥的命令學習實在太難,但是一旦學會就愛不釋手。因爲它的功能實在太強大了。

有很多初學者都會遇到這麼一個問題,自己對系統的每個命令都很熟悉,但是在系統出現故障的時候,就無從下手了,甚至不知道在什麼時候用什麼命令去檢查系統,這是很多Linux新手最無奈的事情了。說到底,就是學習的理論知識沒有很好地與系統實際操作相結合。

很多Linux知識,例如每個命令的參數含義,在書本上說得很清楚,看起來也很容易理解,但是一旦組合起來使用,卻並不那麼容易,沒有多次的動手練習,其中的技巧是無法完全掌握的。

人類大腦不像計算機的硬盤,除非硬盤壞掉或者硬盤被格式化,否則儲存的資料將永遠記憶在硬盤中,而且時刻可以調用。而在人類記憶的曲線中,必須要不斷地重複練習纔會將一件事情記得比較牢。學習Linux也一樣,如果無法堅持學習的話,就會學了後面的,忘記了前面的。還有些Linux初學者也學了很多Linux知識,但是由於長期不用,導致學過的東西在很短的時間內又忘記了,久而久之,失去了學習的信心。

可見,要培養自己的實戰技能,只有勤於動手,肯於實踐,這也是學好Linux的根本。

遇到問題,首先想到的應該是如何自己去解決這個問題,解決方式有很多,比如看書查資料、網絡搜索引擎搜索和瀏覽技術論壇等,通過這幾種方式,90%的問題都能得到解決

獨立思考並解決問題,不但鍛鍊了自己獨立解決問題的能力,在技術上也能得到快速提高如果通過以上方式實在解決不了的話,可以向人詢問,得到答案後要思考爲何這麼做,然後做筆記記錄解決過程。最忌諱的方式是隻要遇到問題,就去問人,雖然這樣可能會很快解決問題,但是長久下去遇到問題就會依賴別人,技術上也不會進步。

二、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功能更加完善,更加強大。

三、shell中的通配符、重定向、管道和引用

Linux下的各種shell的主要區別在於命令行的語法。對於一些普通的命令,各個shell版本的語法基本相同,只有在編寫一個shell腳本或者使用一些shell高級特性的時候,各個版本shell的差異才會顯示出來。

shell語法分析是指shell的對命令的掃描處理過程,也就是把命令或者用戶輸入的內容分解成要處理的各個部分的操作。在Linux系統下,shell語法分析包含很多的內容,例如重定向、文件名擴展和管道等。

本節我們以bash爲例,介紹以下shell命令的語法分析。

3.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

3.2、shell的通配符

通配符主要是爲了方便用戶對文件或者目錄的描述,例如用戶僅僅需要以“.sh”結尾的文件時,使用通配符就

能很方便地實現。各個版本的shell都有通配符,這些通配符是一些特殊的字符,用戶可以在命令行的參數中使用這些字符,進行文件名或者路徑名的匹配。shell將把與命令行中指定的匹配規則符合的所有文件名或者路徑名作爲命令的參數,然後執行這個命令。

bash中常用的通配符有“*”、“?”、“[]”。

(1)“*”——匹配任意一個或多個字符

例如:

[root@WEBServer ~]#ls *.txt

這個命令是列出當前目錄中所有以“.txt”結尾的文件(除去以“.”開頭的文件)。

[root@WEBServer ~]#cp doc/* /opt

表示將doc目錄下的所有文件(除去以“.”開頭的文件)拷貝到/opt目錄下。

[root@WEBServer ~]#ls –al /etc/*/*.conf

列出/etc目錄的子目錄下所有以“.conf”結尾的文件。在/etc目錄下的以“.conf”結尾文件將不會列出。

(2)“?”——匹配任意單一字符

例如:

[root@WEBServer ~]#ls ab?.txt

將列出當前目錄下以ab開頭,隨後一個字母是任意字符,接着以“.txt”結尾的文件。

[root@WEBServer ~]#ls ab??.txt

將列出當前目錄下以ab開頭,隨後的兩個字母是任意字符,接着以“.txt”結尾的文件。

(3)“[]”——匹配任何包含在方括號內的單字符
例如:

[root@WEBServer ~]#ls /dev/sda[12345]
/dev/sda1  /dev/sda2  /dev/sda3  /dev/sda4  /dev/sda5

上面列出了在/dev目錄下以sda開頭,第4個字符是1、2、3、4或5的所有文件。

[root@WEBServer ~]#ls /dev/sda[1-5]

在方括號中“1-5”給出了匹配的範圍,與上面一條命令完全等效。

(4)通配符的組合使用

在Linux下,通配符也可以組合使用,例如:

[root@WEBServer ~]#ls [0-9]?.conf

列出當前目錄下以數字開頭,隨後一個是任意字符,接着以“.conf”結尾的所有文件。

[root@WEBServer ~]#ls [xyz]*.txt

列出當前目錄下以x、y或z開頭,最後以“.txt”結尾的文件。

3.3、shell的重定向

Linux下系統打開3個文件,即標準輸入、標準輸出和標準錯誤輸出。用戶的shell將鍵盤設爲默認的標準輸入,默認的標準輸出和標準錯誤輸出爲屏幕。也就是用戶從鍵盤輸入命令,然後將結果和錯誤信息輸出到屏幕

所謂的重定向,就是不使用系統默認的標準輸入輸出,而是重新指定,因此重定向分爲輸入重定向、輸出重定向和錯誤輸出重定向。要實現重定向就需要了解重定向操作符,shell就是根據重定向操作符來決定重定向操作的

1、輸入重定向

輸入重定向用於改變命令的輸入源,利用輸入重定向,就可以將一個文件的內容作爲命令的輸入,而不從鍵盤輸入

用於輸入重定向的操作符有“<”和“<<”。例如:

[root@WEBServer ~]#wc </etc/shadow
40   40 1169

用wc命令統計輸入給它的文件/etc/inittab的行數、單詞數和字符數。
還有一種輸入重定向“<<”,這種重定向告訴shell,當前命令的標準輸入爲來自命令行中一對分隔號之間的內容。例如:

[root@WEBServer ~]#wc << aa
> # Default runlevel. The runlevels used by RHS are:
> #   0 - halt (Do NOT set initdefault to this)
> #   1 - Single user mode
> #   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
> #   3 - Full multiuser mode
> #   4 - unused
> #   5 - X11
> #   6 - reboot (Do NOT set initdefault to this)
> aa
  8  65 303

上面的命令將一對分隔號aa之間的內容作爲wc命令的輸入。分隔號可以是任意字符。shell將在第一個分隔號後開始讀取內容,直到出現另一個分隔號讀取結束,然後將內容送給wc命令處理。

2、輸出重定向

輸出重定向是將命令的輸出結果不在屏幕輸出,而是輸出到一個指定文件中。

在Linux下輸出重定向用得很多,例如,某個命令的輸出很長,一個屏幕無法顯示完畢,我們可以將命令的輸出指定到一個文件,然後用more命令查看這個文件,從而得到命令輸出的完整信息。

用於輸出重定向的操作符有“>”和“>>”。

例如:

[root@WEBServer ~]#ps –ef >ps.txt

將ps –ef輸出的系統運行進程信息全部輸入到了ps.txt文件,而不輸出到屏幕,可以用more命令查看ps.txt文件中系統運行的進程信息。

[root@WEBServer ~]#more file1 file2 file3 >file

more命令是查看文件的內容,上面的命令是將file1、file2和file3的內容全部輸出到file文件中,類似於文件內容的合併。

如果在“>”後面指定的文件不存在的話,shell就會自動重建一個;如果文件存在的話,那麼這個文件原有的內容將被覆蓋;如果不想覆蓋存在的文件,可以使用“>>”操作符。例如:

[root@WEBServer ~]#ls –al /etc/* >>/root/install.log

將/etc目錄及其子目錄下的所有文件信息追加到/root/install.log文件的後面。/root/install.log文件原來的內容仍然存在。

3、錯誤重定向

錯誤重定向和標準輸出重定向一樣,可以使用操作符“2>”和“2>>”實現對錯誤輸出的重定向。例如:

[root@WEBServer ~]#tar zxvf text.tar.gz 2> error.txt

tar是打包命令,可以在屏幕上看到tar的解壓過程。如果“text.tar.gz”是個損壞的壓縮包,就會把錯誤信息輸出到error.txt文件。

3.4、shell的管道

管道可以把很多命令連接起來,可以把第1個命令的輸出當作第2個命令的輸入,第2個命令的輸出當作第3個命令的輸入,依此類推。因此,管道的作用就是把一個命令的輸出當作下一個命令的輸入,而不經過任何中間文件
通過管道符“|”可以建立一個管道連接,例如:

[root@WEBServer ~]# ls -al /etc/* |more

表示將/etc目錄以及子目錄下的所有文件分屏顯示。

[root@WEBServer ~]#ps -ef|grep httpd|wc –l

這個命令是查看系統中正在運行的httpd進程,並計算httpd的進程數。

3.5、shell中的引用

在bash中有很多特殊字符,這些字符本身就具有特殊含義。如果在shell的參數中使用它們,就會出現問題。Linux中使用了“引用”技術來忽略這些字符的特殊含義,引用技術就是通知shell將這些特殊字符當作普通字符處理。shell中用於引用的字符有轉義字符“\”、單引號“'”、雙引號“" "”。

1、轉義字符“\”

如果將“\”放到特殊字符前面,shell就忽略這些特殊字符的原有含義,當作普通字符對待,例如:

[root@WEBServer ~]#ls
abc?*  C:\backup
[root@WEBServer ~]#mv abc\?\*  abc
[root@WEBServer ~]#mv C\:\\backup backup

上面是將abc?*重命令爲abc,將C:\backup重命名爲backup。因爲文件名中含有特殊字符,所有都使用了轉義字符“\”。

2、單引號“'”

將字符串放到一對單引號之間,那麼字符串中所有字符的特殊含義將被忽略,例如:

[root@WEBServer ~]#mv C\:\\backup backup
[root@WEBServer ~]#mv 'C:\backup'  backup

上面兩條命令完全等效。

3、雙引號“" "”

雙引號的引用與單引號基本相同,包含在雙引號內的大部分特殊字符可以當作普通字符處理,但是仍有一些特殊字符即使用雙引號括起來,也仍然保留自己的特殊含義,比如“$”、“\”和“`”。


[root@WEBServer ~]#str="The \$SHELL Current shell is $SHELL"
[root@WEBServer ~]#str1="\$$SHELL"
[root@WEBServer ~]#echo $str
The $SHELL Current shell is /bin/bash
[root@WEBServer ~]#echo $str1
$/bin/bash

從上面輸出可以看出,“$”和“\”在雙引號內仍然保留了特殊含義。


[root@WEBServer ~]# str="This hostname is `hostname`" 
[root@WEBServer ~]# echo $str
This hostname is WEBServer

上面的輸出中,字符“`”在雙引號中也保留了自己特殊含義。

看到了吧,shell很厲害吧,linux運維工作更多的是與shell打交道,所以學會shell,是學好linux運維的根本。

如何深入學習shell技能

說了這麼多,那麼問題來了,怎麼能快速學好shell,能夠編寫高質量的shell腳本提高運維效率呢,我將多年來企業一線工作經驗進行了總結和提煉,寫成了專欄《神奇高效的Linux命令行》點擊前往,15篇文章打通shell任通二脈,讓經驗和案例說話:

專欄《神奇高效的Linux命令行》點擊前往

此專欄能學到什麼技能:

神奇高效的Linux命令行

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