如何系統地學習Shell編程學習指南?
看了很多的Shell學習計劃,但是最后都沒有完成,下面說說我們馬哥Linux學習社群的一個人的經歷。
引言:什么是Shell?
Linux的命令行接口歸結起來就是各種Shell,那么到底什么是Shell?
Shell,譯為外殼,是用戶直接連入計算機所使用的計算機程序,負責解析用戶提供的命令,如詞法分析、語法分析、句法分析。
1.Shell的分類
Linux 的命令 shell 是與操作系統相分離的一層。不同的 shell 環境影響您具備不同的功能,比如可編輯的命令行和歷史命令回查等。shell 還決定了腳本中函數的語法。
下面就列舉幾個常用的Shell:
1. ?bash
bash shell 是 Bourne shell 的一個免費版本,它是最早的 Unix shell,包括許多附加的特點。Bash 有可編輯的命令行,可以回查歷史命令,支持 tab 鍵補齊以使用戶避免輸入長的文件名。
2. ?csh
C shell 使用的是“類C”語法,借鑒了 Bourne shell 的許多特點,只是內部 shell 命令集有所不同。
3. ?ksh
Korn shell 的語法與 Bourne shell 相同,同時具備了 C shell 的易用特點。許多安裝腳本都使用 ksh ,即使您不把它作為您的主 shell,您也應該在系統中安裝它。
4. ?tcsh?
TC shell 是 C shell 的一個增強版本,與 C shell 完全兼容。
5. ?zsh
Z shell 是 Korn shell 的一個增強版本,具備 bash shell 的許多特色。
> 默認的 shell 是每個用戶帳號的一個參數。Linux 中典型的默認 shell 是 /bin/bash,不過也可以用其他的 shell。每個 shell 的 man 文檔實際上都非常好,都對各種 shell 及其使用進行了詳細的說明。
一:起因
(0)也許由于一時的沖動使得你開始關注并學習shell編程;亦許由于是“道聽途說”shell的威力很大;亦許由于shell編程的魅力;亦許由于作為一個coder的偏好;亦許……
(1)先來搞清楚為什么要學shell,學習要有目的性 ---- 簡單的說shell就是一個包含若干行Shell或者Linux命令的文件。對于一次編寫,多次使用的大量命令,就可以使用單獨的文件保存下來,以便日后使用。
shell簡單、靈活、高效,特別適合處理一些系統管理方面的小問題
shell可以實現自動化管理,讓系統管理員的工作變得容易、簡單、高效
shell可以把一些經常需要用的命令或者操作,以文件的形式存儲起來,每一次調用即可,不用重復的鍵入命令
shell腳本可移植性好,在unix/Linux系統中可靈活移植,幾乎不用任何設置就能正常運行
shell腳本可輕松方便讀取和修改源代碼,不需要編譯 掌握shell可以幫你解決一些故障問題,比如腳本引起的故障問題
掌握shell是一個中級以上系統工程師必需要會的 掌握shell是你系統管理進階的必經之路
掌握shell是你面試更高級職位的一塊敲門磚
(2)那什么時候不使用Shell 腳本?
資源密集型的任務,尤其在需要考慮效率時(比如排序,hash 等)
需要處理大任務的數學操作,尤其是浮點運算,精確運算,或者復雜的算術運算(這種情況一般使用C++或FORTRAN 來處理)
有跨平臺移植需求(一般使用C 或Java) 復雜的應用,在必須使用結構化編程的時候(需要變量的類型檢查,函數原型,等等)
對于影響系統全局性的關鍵任務應用。 對于安全有很高要求的任務,比如你需要一個健壯的系統來防止入侵,破解,惡意破壞等等. 項目由連串的依賴的各個部分組成。
需要大規模的文件操作 或 需要多維數組的支持 需要數據結構的支持,比如鏈表或數等數據結構
需要產生或操作圖形化界面 GUI 需要直接操作系統硬件 需要 I/O 或socket 接口
需要使用庫或者遺留下來的老代碼的接口 私人的,閉源的應用(shell 腳本把代碼就放在文本文件中,全世界都能看到)
如果你的應用符合上邊的任意一條,那么就考慮一下更強大的語言吧--或許是Perl,Python,Ruby, 或者是更高層次的編譯語言比如C/C++,Java
二:知識點介紹
(1)從腳本編寫和執行開始 —— 編寫用vim即可,保存為filename.sh文件即可;執行前需要更改為可執行文件或者sh filename.sh來執行:
1)通常shell腳本以.sh為后綴。在編寫shell時,第一行一定要指明系統需要哪種shell解釋用戶的shell程序,如:#!/bin/sh,#!/bin/bash,#!/bin/csh,,#!/bin/tcsh和,#!/bin/ksh等。下面的run.sh則指明使用bash執行。 #!bin/bash ls -l 通常,shell腳本會以#!/bin/sh作為默認的shell程序。執行shell的方式有兩種:第一種是為shell腳本加上可執行權限并執行,第二種是通過sh命令執行shell腳本,例如執行當前目錄下的run.sh腳本,命令如下: //為shell腳本直接加上可執行權限并執行 chmod 755 run.sh ./run.sh
2)//通過sh命令執行shell腳本
sh run.sh 注意:那為何『 sh shell.sh 』也可以運行呢? 這是因為 /bin/sh 其實就是 /bin/bash(連結檔),使用 sh shell.sh 亦即告訴系統,我想要直接以 bash 的功能來運行 shell.sh 這個文件內的相關命令的意思,所以此時你的 shell.sh 只要有 r 的權限即可被運行喔!而我們也可以利用 sh 的參數,如 -n 及 -x 來檢查與追蹤 shell.sh 的語法是否正確呢 sh -x filename.sh 這會執行腳本并顯示腳本中所有變量的取值,也可以使用參數-n,它并不執行腳本,只是返回所有的語法錯誤。 (2)下面我們從經典的“hello world”入手,看一看最簡單的Shell腳本的模樣
sudo vim hello.sh:
#!/bin/sh #print hello world in the console window a="hello world" echo "Hi, ${a}s"
chmod 755 hello.sh 更改為可執行文件 rwx(4,2,1)
sh hello.sh 或者 ./hello.sh
(3)shell里的特殊字符
和其他編程語言一樣,shell里也有特殊字符。常見的有美元符號($),反斜線(\)和引號。
1)美元符號
美元符號表示變量替換,即用其后面指定的變量的值來代替變量。反斜線“\”為轉義字符,轉義字符告訴shell不要對其后面的那個字符進行特殊處理,只是當做普通字符。
2)雙引號(")
由雙引號括起來的字符,除$,倒引號(`)和反斜線(\)仍保留其特殊功能外,其余字符均作為普通字符對待。 3)單引號(') 由單引號括起來的字符都作為普通字符出現。
4)倒引號(`) tab鍵上面那個原始字符
由倒引號括起來的字符串被shell解釋為命令行,在執行時,shell會先執行該命令,并以它的標準輸出結果取代整個引號部分。
5)示例
示例1的代碼及輸出如下: #echo "My current directory is `pwd` and logname is $LOGNAME"【雙引號中的倒引號和美元符號保持原來的功能】 My current directory is /root and logname is root 示例2的代碼及輸出如下: #echo "My current directory is `pwd` and logname is \$LOGNAME"【雙引號中的轉義字符保持原來的功能】 My current directory is /root and logname is $LOGNAME 示例3的代碼及輸出如下: #echo 'My current directory is `pwd` and logname is $LOGNAME'【單引號里面的內容不變】 My current directory is `pwd`and logname is $LOGNAME
6)變量
shell的變量非常類似于JS 和 Python,不用聲明;但是有一點需要注意,變量和等號(即等號前后無任何空格)如 num=10;但是if [ ${num} eq 10 ];then …… fi 這其中的空格必須得有的
(4)shell腳本的注釋
shell腳本和其它編程語言一樣,也擁有注釋。注釋方法為在注釋行前加#號。 例如以下腳本: #!/bin/sh #Filename: comment.sh #Description:this script explains how to make a comment echo “This script explains how to make a comment ”
創建腳本時,腳本的第一行通常稱為shbang(#!)行。當腳本啟動后,UNIX內核檢查文件的第一行以決定將要執行的程序類型。
shbang符號(#!)后面的路徑是用來解釋此腳本的shell位置。要正確使用這個特性,#!必須是文件中最前面的兩個字符。如果 文件頭部有空格字符或者空白行,則此特性被忽略,該行被解釋為普通的注釋行。
(5)再看sh腳本執行的奧秘
打開文本編輯器,新建一個文件,擴展名為sh(sh代表shell),擴展名并不影響腳本執行,見名知意就好,如果你用php寫shell 腳本,擴展名就用php好了。
輸入一些代碼:
#!/bin/bash
echo "Hello World !"
“#!” 是一個約定的標記,它告訴系統這個腳本需要什么解釋器來執行,即使用哪一種Shell。echo命令(最好用$printf ""具有更好的可移植性)用于向窗口輸出文本。
將上面的代碼保存為test.sh,并 cd 到相應目錄:
chmod +x ./test.sh #使腳本具有執行權限
./test.sh #執行腳本
注意,一定要寫成./test.sh,而不是test.sh。運行其它二進制的程序也一樣,直接寫test.sh,Linux系統會去PATH里尋找有沒有叫test.
sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH里,你的當前目錄通常不在PATH里,所以寫成test.sh是會找不到命令的,要用./test.sh告訴系統說,就在當前目錄找。
通過這種方式運行bash腳本,第一行一定要寫對,好讓系統查找到正確的解釋器。
這里的"系統",其實就是shell這個應用程序(想象一下Windows Explorer),但我故意寫成系統,是方便理解,既然這個系統就是指shell,那么一個使用/bin/sh作為解釋器的腳本是不是可以省去第一行呢?是的。
三:體會心得
(1)簡單的說shell就是一個包含若干行Shell或者Linux命令的文件。對于一次編寫,多次使用的大量命令,就可以使用單獨的文件保存下來,以便日后使用。
例如:你用c編寫一個工程,里面有很多.h文件,.c文件等等,每一次更改你都得需要重新 g++ filenames.c filenames.h -o filenames,過于麻煩,這時就需要編寫一個小小shell文件,就可以解決問題了。
(2)記得自己上次寫Python的基礎學習,應該是一個月前了,這次重新學一個新的語言(腳本語言),間隔的時間非常短;越發的感覺,必須掌握精通一門語言,之后學習其他語言非常容易上手 —— 僅僅是入門,如果想在某一門語言上進階或者深入,只能說“路漫漫其修遠兮亦”!