Shell腳本編程總結及速查手冊

Shell是一種編程語言, 它像其它編程語言如: C, Java, Python等同樣也有變量/函數/運算符/if語句/循環控制/… 但在開始以前, 我想先理清Shell語言與Shell之間的關係.html

Shell與Shell語言

上面說了Shell是一種編程語言但你可能也據說過: sh/bash/csh/zsh/…它們也叫Shell, 實際上這裏所說的Shell是一種應用程序, 它負責解釋執行你編寫的Shell腳本, Mac默認就自帶了sh/bash/csh/zsh/tcsh/ksh, 你能夠這樣查看cat /etc/shells 不一樣的shell的用法基本相同, 但有些shell提供了一些新特性, 好比我如今在用的就是zsh, 更多zsh的內容能夠去看這篇文章shell

第一個Shell腳本

 

 

1express

2編程

#! /bin/shbash

echo "hello shell!"hexo

依國際慣例這裏以在終端裏打印一句hello shell!開始, 第一行的#!是一個約定標記, 它告訴腳本這段腳本須要什麼解釋器來執行. 第二行的echo命令則負責向屏幕上輸出一句話.框架

如何運行

運行shell程序有3種方法:編程語言

  1. chmod +x使文件具備可執行權限, 直接運行
  2. 直接調用解釋器, 將腳本文件做爲參數傳入 (好比bash hi.sh)
  3. 使用source(也可用 . 代替)執行文件

一般狀況下, 最方便的方式就是方式1, 經過方式1執行你須要在腳本第一行寫好這段腳本由哪一個解釋器來解釋, 而經過方式2來執行則沒有這個限制, 寫了也沒用. 除此以外方式1與方式2執行命令就沒有區別了, 但方式3執行的方式與前兩種都不一樣:函數

使用source執行shell腳本時, 不會建立子進程, 而是在父進程中直接執行!post

這裏不做更多解釋, 感興趣的同窗能夠去參考Linux Shell編程從入門到精通這本書的第一章的相關部分.

變量

和其它語言同樣Shell中也有變量, 並且更簡單, 但有一些比較特殊的地方.

  1. Shell中的變量只有字符串這一種類型
  2. Shell中變量名與變量值沒有長度限制
  3. Shell的變量也容許比較操做和整數操做, 只要變量中的字符串爲數字

定義變量

 

 

1

variable_name=ghui

須要注意: = 兩邊不能加空格, 當賦值語句包含空格時請加引號(單引號/雙引號都可)好比:

 

1

variable_name="ghui's blog"

Shell中的變量能夠分爲兩種類型:

  1. 局部變量 (定義變量時在前面加local修飾符)
  2. 全局變量 (定義變量時不加任何修飾符)

與其它語言同樣局部變量的可見範圍是代碼塊或函數內, 全局變量在全局範圍內可見.看個簡單的例子:

 

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

更多關於字符串的操做能夠看這個

if/else流程控制

基本語法結構:

 

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流程控制

當條件較多時, 能夠選擇使用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:

  1. ;;至關於其它語言中的break
  2. 每一個pattern以後記得加)
  3. 最後記得加esac (即反的case)

for循環

基本結構:

 

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文件, 並依次打開.

while循環

基本結構:

 

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: 你可能須要去了解一下(())的用法

until循環

基本結構

 

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:

  1. 函數必須先定義後使用
  2. 若是在函數中使用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

 

後記

之因此要寫這篇博客, 有如下幾個緣由:

  1. 想總結一下shell編程中的關鍵知識點, 方便往後查看.
  2. 想經過shell優化一下個人hexo寫做及博客管理流程, 目前相關腳本已完成, 待我下一篇博客分享給你們, 若是你也是在用Hexo寫博客, 相信對你會頗有用, 盡請期待! 已經發布
  3. 能夠看的出這裏總結的都是最關鍵的知識點, 還有不少這裏並無說. 是由於我以爲剛開始學習一個東西不必太計較一些細節/瑣碎的東西, 掌握好大體知識框架, 而後在你們編寫具體的腳本時, 遇到具體問題, 再去google尋找便可.
相關文章
相關標籤/搜索