linux shell 腳本編程基本語法

linux shell腳本編程基本語法

Shell script是利用shell的功能所寫的一個“程序”,這個程序是使用純文本文件,將一些Linux Shell的語法與命令(含外部命令)寫在裏面,搭配正則表達式、管道命令與數據流重定向等功能,以達到我們所想要的處理目的。Shell script提供數組、循環、條件與邏輯判斷等重要功能,讓用戶也可以直接以shell來編寫程序,而不必使用類似C程序來完成相關功能。Shell Script就像是早期DOS年代的批處理文件(.bat)。

編程格式

在寫C程序的時候,代碼的開頭我們通常會給版本信息。shell腳本也不例外。
一般聲明如下。

#!/bin/sh
# Program:
#   This program shows "Hello World" in your srceen
# History:
#   2017-6-5 liwanneng  V1.0.0

echo -e "Hello world"
  • 第一行 #!/bin/sh 聲明該shell script使用的shell名稱,linux默認使用的是bash shell
  • 第二行Program後面是程序內容的說明,這個shellscript中,除了第一行外,其他#符號表示註釋
  • 第四行History後面是時間,作者以及版本信息
  • 從echo開始,後面表示程序正文

shell script中常見語法

從屏幕中獲取輸入

在shell script中,使用read -p 來獲取標準輸入
例如

#!/bin/sh
# Program:
#   This program User input his first name and last name, Program shows his full name
# History:
#   2017-6-5 liwanneng  V1.0.0
read -p "Please input your first name:" firstname #提示用戶輸入,末尾的first爲變量名
read -p "Please input your last name:" lastname 
echo -e "/nYour full name is :$firstname $lastname" #結果由屏幕輸出

其輸出結果如圖
這裏寫圖片描述

數值運算,簡單的加減乘除

在shell script腳本中,可以使用$( (計算式) )來進行整數數值運算

#!/bin/sh
# Program:
#   This program 
# History:
#   2017-6-5 liwanneng  V1.0.0

echo -e "Please Input TWO numbers\n"
read -p "the first number is:" num1#提示用戶輸入,末尾的num1爲變量名
read -p "the second number is:" num2
product=$(($num1*$num2)) 
sum=$(($num1+$num2)) 
red=$(($num1-$num2)) 
div=$(($num1/$num2)) 
echo -e "$num1 x $num2 = $product"
echo -e "$num1 + $num2 = $sum"
echo -e "$num1 - $num2 = $red"
echo -e "$num1 ÷ $num2 = $div"

結果:
這裏寫圖片描述

shell script中的默認變量($0, $1…)

在bashshell中,$0表示腳本程序本身,$1表示腳本程序後面跟的第一個參數,以此類推,$2表示腳本程序後面跟的第二個參數。除了這些數字變量之外,還有一些較爲特殊的變量可以在script中使用來調用這些參數。
* $#:表示腳本程序後面跟的參數個數
* \$@:表示 “\$1”, “\$2”, “\$3”之意,每個變量是獨立的。
* \$*:表示”\$1c\$2c\$3”,其中c爲分隔字符,默認爲空格鍵。
來看個例子

#!/bin/sh
# Program
#   Program shows script name, paramters...
# History
#   2017-6-4
echo -e "The script name is $0"
echo -e "Total parameter numher is $#"
[ "$#" -lt 2 ] && echo -e "The number of paramter is less than 2. Stop here.    " && exit 0
echo -e "Your whole paramter is $@"
echo -e "Your first paramter is $1"
echo -e "Your second paramter is $2"

執行結果
這裏寫圖片描述

shell script中的判斷

test命令的測試

在linux中,可以使用test命令來測試系統上面某些文件的相關屬性。例如,我要檢查sh01.sh是否存在使用:test -e ./sh01.sh
單獨執行該命令不會顯示任何結果,我們可以在後面加上&&以及||來顯示結果,如圖:
這裏寫圖片描述
其中 test命令後面跟的 -e表示:判斷文件是否存在。除了-e外,test還可以跟其他許多的參數來獲取文件或變量的相關屬性如

  • 關於某個文件名的文件類型判斷,如 test -e filename
    -e:該文件名是否存在
    -f:該文件名是否存在且爲文件
    -d:該文件名是否存在且爲目錄
    -b:該文件名是否存在且爲塊設備文件
    -c:該文件名是否存在且爲字符設備文件
    -S:該文件名是否存在且爲socket文件(大寫S)
    -p:該文件名是否存在且爲FIFO文件
    -L:該文件名是否存在且爲鏈接文件
  • 關於文件的權限檢測,如test -r filename
    -r:該文件名是否存在且具有“可讀”權限
    -w:該文件名是否存在且具有“可寫”權限
    -x:該文件名是否存在且具有“可執行”權限
    -u:該文件名是否存在且具有“SUID”屬性
    -g:該文件名是否存在且具有“SGID”屬性
    -k:該文件名是否存在且具有“sticky bit”屬性
    -s:該文件名是否存在且爲“非空白文件”(小寫s)
  • 兩個文件之間的比較,如:test file1 -nt file2
    -nt:newer than,判斷file1是否比file2新
    -ot:older than,判斷file1是否比file2舊
    -ef:判斷file1與file2是否爲同一文件,可用在判斷hard link的判定上。主要意義在於判定兩個文件是否指向統一個inode
  • 關於兩個整數之間的判定,如test num1 eq num2
    -eq:equal,num1等於num2
    -ne:not equal,num1不等於num2
    -gt:greater than,num1大於num2
    -lt:less than,num1小於num2
    -ge:great equal,num1大於等於num2
    -le:less equal,num1小於等於num2
  • 判定字符串的數據
    test -z string:判定字符串是否爲0,若string爲空字符串,則爲true
    test -n string:判定字符串是否爲非零,若string爲空字符串,則爲false
  • 多重條件判定,例如:test -r filename -a -x filename
    -a:兩個條件同時成立!例如 test -r file -a -xfile,則file同時具有 r 與 x 權限時,纔回傳true
    -o:任何一個條件成立!例如 test -r file -o -x file,則file具有 r 或者 x 權限時,纔回傳true
    !:反向狀態!如test !-x file,當file不具有x時,回傳true。

利用判斷符號[]

除了利用test命令判斷外,我們可以利用判斷符號“[]”(英文輸入狀態下的中括號)來進行數據的判斷。這個符號在shell script中經常與if條件判斷搭配使用。
在bash的語法中使用“[]”做判斷必須要注意的幾點
1. 中括號兩端需要空格符來分隔
2. 在中括號[]內每個組件都需要有空格來分隔
3. 中括號內的變量和常量最好都用雙引號括起來

假如我空格號使用“口”符號來表示,那麼在這些地方需要有空格。

口[口"$HOME"口==口"$MAIL"口]口

上面這句話的意思是變量HOME與變量MAIL是否相同的意思,相當於test$HOME=$MAIL

條件判斷式

if… then是shell script中常用到的條件判斷式。簡單來說就是當符合某項條件的時候,就進行某項工作。其格式一般爲

if [ 條件1 ] ; then
   程序段
#在shell script中用elif,功能類似於C語言中的else if語句
elif [ 條件2 ]; then
   程序段
else
   程序段
fi   #fi表示if的結束

下面來看一個例子

 #!/bin/sh
 # Program
 #   This program shows user's choice
 # History
 #   2017-6-4 liwanneng V1.0.0
read -p "Please input Y/N:" yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
      echo "Clever boy! You will Continue"
      exit 0
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
      echo "You will interrupt the program!!!"
      exit 0
else
      echo "Please input Y/y or N/n!"
      exit 0
fi

運行結果如下:
這裏寫圖片描述

利用case…esac判斷

在shell script中除了用if…then語句來判斷,我們還可以使用case…esac來表示多重條件判斷,類似於C語言中的Case語句。其格式爲:

case $變量名稱 in  #關鍵字爲case,還有$符號
   "第一個變量內容") #每個變量內容用括號括起來,關鍵字則爲小括號
      程序段
      ;;  #每個類型的結尾使用英文輸入法狀態下的兩個分號來表示
   "第二個變量內容")
      程序段
      ;;
   *) #最後一個變量使用*來表示其他值
      exit 1
      ;;
easc  #由esac來表示case語句的最終結尾

來看一個例子

 #!/bin/sh
   # Program
   #   Program show "hello" from $1...by using case ...esac
   # History
   # 2017-6-4 10:32:33

   case $1 in
       "hello")
           echo "Hello,how are you!"
          ;;
      "bye")
          echo "bye-bye!"
          ;;
      "") #如果沒有輸入
          echo "You must input parameter, ex> {$0 someword}"
          ;;
      *)
          echo "use $0 {hello or bye}"
          ;;
  esac

來看程序執行的結果
這裏寫圖片描述

whlie do done,until do done 不定循環

在C語言中,經常用到whle循環和for循環來表示程序的反覆執行。在shell script中同樣有while循環和for循環,只是shell script 中的while和for 的用法與C語言中稍有不同。

while do done不定循環

在shell script中while…done不定循環的常見格式如下

while [ condition ] #中括號內的狀態就是判斷式   
do #do是循環的開始
done  #done是循環的結束

while的在英語中的意思是“當…時”,所以while…done這種循環表示當condition條件成立時就進行循環,直到condition條件不成立時才停止循環。
來看一個例子

  #!/bin/sh
   # Program
   #   Repet quesstion until input correct answer.
   # History
   #   2017-6-6 liwanneng V1.0.0

  while [ "$yn" != "yes" -a "$yn" != "YES" ]
  do
       read -p "Please input yes/YES to stop this program:" yn
  done
  echo -e "OK,you input the correct answer."

上面這個程序爲:當滿足條件 “$yn” != “yes” -a “$yn” != “YES” 即輸入不爲yes/YES時,程序一直循環,調用read語句一直等待用戶輸入。當不滿足條件 “$yn” != “yes” -a “$yn” != “YES” 即輸入爲yes/YES時,程序退出循環,調用echo語句。程序執行結果如圖。
這裏寫圖片描述

until do done不定循環

在shell script中還有一種不定循環 until do done循環,這種循環恰恰與while相反,它是當條件成立時才進行循環,條件不成立時,程序退出循環。其一般格式如下

ubtil [ condition ]
do
    程序段
done 

同樣來看一個例子

#!/bin/sh
# Program
#   Repeat question ubtil user input correct answer
# History
#   2017-6-6 liwanneng V1.0.0

until [ "$yn" == "yes" -o "$yn" == "YES" ]
do
  read -p "Please input yes/YES to stop the program:" yn
done
echo -e "Ok,you input correct answer."

程序執行結果和上面有while循環的程序執行結果一樣。但是程序邏輯卻有所區別。當不滿足條件”$yn” == “yes” -o “$yn” == “YES” 即輸入不爲yes或YES的時候,程序一直循環,調用read語句等待用戶輸入。直到滿足條件 “$yn” == “yes” -o “$yn” == “YES” 即輸入爲yes 或 YES的時候,程序退出循環,執行echo語句。
這裏寫圖片描述

for … do … done固定循環以及數值處理

相對於while,until的循環方式是必須要“符合某個條件”,for循環則是“已經知道要循環幾次”的狀態。它的語法是

for var in con1 con2 con3 #var爲變量,con1,con2,con3分別爲條件1,條件2,條件3
do
    程序段
done

上面這段例子的意思是,當變量var1. var的內容爲con1
2. 第二次循環時,varcon23. var的內容爲con3

來看一個具體的例子,加入有三種動物分別是cat,dog,bird,每一行都輸出一種動物,程序可以寫爲:

#!/bin/sh
# Program 
#   Using for ...loop to print 3 animal
# History
#   2017-6-6 liwanneng V1.0.0
for animal in dog cat bird
do
    echo "There is ${animal}..."
done

程序執行結果如下
這裏寫圖片描述

for… do… done的數值處理

除了上面的方法外,for循環還有另外一種寫法,也就是C語言中for循環的用法,語句如下:

for ( ( 初始值;限定值;執行步長) )
do
    程序段
dne

for後面三串內容的意義:
1. 初始值:某個變量在循環中的初始值,比如常見的 i=1;
2. 限定值:當變量在限定值範圍之內,程序一直循環直到超出限定值,如 i<=100;
3. 執行步長:沒做一次循環的變化量,如i = i+1;
來看一個具體的例子,輸入一個數字num,程序做1+2+3…+num運算

#!/bin/sh
# Program
#   Caculate 1+2+3+...$(input)
# HIstory
#   2017-6-6 liwanneng V1.0.0
read -p "Please input a num:" num
for(( i=1; i<$num; i=i+1 ))
do
    sum=$(($sum+$i))
done
echo "The result of 1+2+3+...$num is:$sum" 

來看程序執行結果
這裏寫圖片描述

function函數功能

在C語言中我們經常自己封裝函數來表示執行同樣功能的一段代碼,在shell script中同樣有function功能。其一般格式爲

function fname(){
 程序段
}

fname爲封裝函數的名字,需要注意的是在shell script中不能像C語言一樣現在調用函數之前聲明,然後可在調用函數之後實現其內容,而只能在調用fname之前就要實現其內容。話不多說,來看例子

#!/bin/sh
# Program
# Use function to repeat information
# History
# 2017-6-6 liwanneng V1.0.0
function printit(){
    echo -n "Your choice is :" #加上-n可以不斷行繼續在同一行顯示
}

echo "This program will print your selection."
case $1 in
"one")
     printit;echo $1 | tr 'a-z' 'A-Z'#將小寫轉換成大寫
     ;;
 "two")
     printit;echo $1 | tr 'a-z' 'A-Z'
     ;;
 "three")
     printit;echo $1 | tr 'a-z' 'A-Z'
     ;;
 *)
     echo "Usage $0 {one|two|three}"
     ;;
  esac

程序執行結果:
這裏寫圖片描述

shell script的追蹤與調試

是程序就一定有bug,如果程序出了錯,在C語言中我們又自己的調試方法。在shell script中有沒有辦法調試程序呢,答案是有的。我們可以直接以bash的相關參數來進行判斷。sh -n/v/x script.sh

  • -n:不要執行script,僅查詢語法是否正確
  • -v:執行script之前,先將script的內容輸出到屏幕
  • -x:將使用到的script內容顯示到屏幕上(經常用到)

懂了以上這些shell腳本編程語法,一般的shell腳本程序看懂應該沒問題了。但是要想自己會寫shell腳本程序,還得多加練習!多加練習!多加練習!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章