Shell是一種編程語言, 它像其它編程語言如: C, Java, Python等同樣也有變量/函數/運算符/if語句/循環控制/… 但在開始以前, 我想先理清Shell語言與Shell之間的關係.html
上面說了Shell是一種編程語言但你可能也據說過: sh/bash/csh/zsh/…它們也叫Shell, 實際上這裏所說的Shell是一種應用程序, 它負責解釋執行你編寫的Shell腳本, Mac默認就自帶了sh/bash/csh/zsh/tcsh/ksh, 你能夠這樣查看cat /etc/shells
不一樣的shell的用法基本相同, 但有些shell提供了一些新特性, 好比我如今在用的就是zsh, 更多zsh的內容能夠去看這篇文章shell
1express 2編程 |
#! /bin/shbash echo "hello shell!"hexo |
依國際慣例這裏以在終端裏打印一句hello shell!開始, 第一行的#!是一個約定標記, 它告訴腳本這段腳本須要什麼解釋器來執行. 第二行的echo命令則負責向屏幕上輸出一句話.框架
運行shell程序有3種方法:編程語言
bash hi.sh
)一般狀況下, 最方便的方式就是方式1, 經過方式1執行你須要在腳本第一行寫好這段腳本由哪一個解釋器來解釋, 而經過方式2來執行則沒有這個限制, 寫了也沒用. 除此以外方式1與方式2執行命令就沒有區別了, 但方式3執行的方式與前兩種都不一樣:函數
使用source執行shell腳本時, 不會建立子進程, 而是在父進程中直接執行!post
這裏不做更多解釋, 感興趣的同窗能夠去參考Linux Shell編程從入門到精通這本書的第一章的相關部分.
和其它語言同樣Shell中也有變量, 並且更簡單, 但有一些比較特殊的地方.
1 |
variable_name=ghui |
須要注意: = 兩邊不能加空格, 當賦值語句包含空格時請加引號(單引號/雙引號都可)好比:
1 |
variable_name="ghui's blog" |
Shell中的變量能夠分爲兩種類型:
local
修飾符)與其它語言同樣局部變量的可見範圍是代碼塊或函數內, 全局變量在全局範圍內可見.看個簡單的例子:
1 2 3 4 5 6 7 8 9 10 11 12 |
#! /bin/sh num=111 #全局變量
func1() { local num=222 #局部變量 echo $num }
echo "before---$num" func1 echo "after---$num" |
輸出:
1 2 3 |
before---111 222 after---111 |
使用一個定義過的變量, 只要在變量名前面加$便可, 如:
1 2 3 |
name=ghui echo $name echo ${name} #{} 爲了幫助解釋器識別變量邊界, 非必須 |
在使用變量時還有一個地方須要注意, 請看下面的例子:
1 2 3 4 |
#! /bin/sh str='abc' echo "1 print $str" echo '2 print $str' |
輸出:
1 2 |
1 print abc 2 print $str |
即: 被雙引號括起來的變量會發生變量替換, 單引號不會
Shell中註釋使用#, 並且它不支持多行註釋.
1 2 3 4 |
name="shell" sayHi="hello, "$name" !" sayHi2="hello, ${name} !" echo $sayHi $sayHi2 |
注意: 上面說的單雙引號引發的變量替換問題
1 2 |
string="abcd" echo ${#string} #輸出:4 |
1 2 3 |
str="hello shell" echo ${str:2} #輸出: llo shell echo ${string:1:3} #輸出:ell |
更多關於字符串的操做能夠看這個
基本語法結構:
1 2 3 4 5 6 7 8 9 10 11 12 |
if condition then do something elif condition then do something elif condition then do something else do something fi |
其中, elif語句和else語句非必須的.看個例子:
1 2 3 4 5 6 7 8 9 10 11 12 |
#! /bin/sh a=1 if [ $1=$a ] then echo "you input 1" elif [ $1=2 ] then echo "you input 2" else #do nothing echo " you input $1" fi |
很簡單, 不過這裏有兩個地方須要注意, 若是某個條件下的執行體爲空, 則你就不能寫這個條件 即下面這樣會報錯:
1 2 3 4 5 6 7 8 9 |
if condition then #do nothing elif condition then # do nothing #or else #do nothing |
另外, [ ]
兩邊必定要加空格, 下面這樣都會報錯:
1 2 3 4 5 |
if [$a=$b] #or if [ $a=$b] #or if [$a=$b ] |
只有這樣if [ $a=$b ]
纔是對的. 注意: 實際上這裏的[]是test命令的一種形式, [是系統的一個內置命令,存在路徑是/bin/[
,它是調用test命令的標識, 右中括號是關閉條件判斷的標識, 所以下面的兩個測試語句是等效的:
1 2 3 4 |
if test "2>3" then ... fi |
和
1 2 3 4 |
if [ "2>3" ] then ... fi |
除[]以外, shell語言中還有幾種其它括號, 好比: 單小括號/雙小括號/雙中括號/… , 不一樣的括號有不一樣的用法, 更多關於shell中, 括號的用法能夠看看這個
當條件較多時, 能夠選擇使用switch語句, shell中的switch語句的寫法和其它語言仍是有些不一樣的, 基本結構以下:
1 2 3 4 5 6 7 8 9 |
case expression in pattern1) do something... ;; pattern2) do something... ;; pattern2) do something... ;; ... esac |
看個例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#! /bin/sh input=$1 case $input in 1 | 0) str="一or零";; 2) str="二";; 3) str="三";; *) str=$input;; esac echo "---$str" |
這個例子會根據你執行此腳本時傳入的參數不一樣在屏幕上輸出不一樣的值, 其中第一個case 1 | 0
表明邏輯或. NOTE:
;;
至關於其它語言中的break
)
esac
(即反的case)基本結構:
1 2 3 4 |
for name [in list] do ... done |
其中,[]括起來的 in list
, 爲可選部分, 若是省略in list
則默認爲in "$@"
, 即你執行此命令時傳入的參數列表. 看個例子:
1 2 3 4 |
for file in *.txt do open $file done |
遍歷當前目錄下的全部txt文件, 並依次打開.
基本結構:
1 2 3 4 |
while condition do do something... done |
看個例子:
1 2 3 4 5 6 7 |
#! /bin/sh i=0 while ((i<5)); do ((i++)) echo "i=$i" done |
輸出:
1 2 3 4 5 |
i=1 i=2 i=3 i=4 i=5 |
NOTE: 你可能須要去了解一下(())
的用法
基本結構
1 2 3 4 |
until condition do do something... done |
看個例子:
1 2 3 4 5 6 7 |
#! /bin/sh i=5 until ((i==0)) do ((i--)) echo "i=$i" done |
輸出:
1 2 3 4 5 |
i=4 i=3 i=2 i=1 i=0 |
shell中也支持break
跳出循環, continue
跳出本次循環.用法與C, Java中相同
要定義一個函數, 可使用下面兩種形式:
1 2 3 4 |
function funcname() { do something } |
或者
1 2 3 4 |
funcname () { do something } |
看個例子
1 2 3 4 5 6 7 8 9 10 |
#! /bin/sh # ad.sh 計算sum add() { let "sum=$1+$2" return $sum }
add $1 $2 echo "sum=$?" |
輸入
1 |
ad 1 2 |
輸出
1 |
sum=3 |
其中, $?
在shell中保存的是上一條命令的返回值
NOTE:
exit
會退出腳本, 若是想退回到本來函數調用的地方, 則可以使用return
先shell腳本傳遞參數, 很是簡單, 只須要在你執行命令的後面跟上便可, 看個例子:
1 2 3 4 5 6 |
#! /bin/sh # test.sh echo "$# parameters"; echo "$@"; echo "$0" echo "$1" |
輸入:
1 |
test.sh 11 22 |
輸出:
1 2 3 4 |
2 parameters 11 22 test.sh 11 |
之因此要寫這篇博客, 有如下幾個緣由: