1. 程式人生 > >零基礎學習Shell程式設計

零基礎學習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的基礎學習,應該是一個月前了,這次重新學一個新的語言(指令碼語言),間隔的時間非常短;越發的感覺,必須掌握精通一門語言,之後學習其他語言非常容易上手 —— 僅僅是入門,如果想在某一門語言上進階或者深入,只能說“路漫漫其修遠兮亦”!

(3)我在這裡就不誤人子弟了,詳細的shell入門詳見 鳥哥私房菜  或者 shell指令碼教程