標籤: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指令碼教程
零基礎學習Shell編程