linux操做系統5 shell編程

知識內容:linux

1.shell編程預備知識shell

2.shell變量編程

3.表達式與運算符數組

4.分支循環語句安全

5.函數bash

 

 

 

1、shell編程預備知識編程語言

1.什麼是shell編程編輯器

shell是與linux交互的基本工具,是一個命令解釋器,它的做用是解釋執行用戶輸入的命令及程序等,有兩種執行命令的方式,以下所示:函數

  • 交互式,用戶每輸入一條命令,shell就解釋執行一條
  • 批處理(batch),須要事先編寫一個shell腳本,其中包含若干條命令,讓shell一次將這些命令執行完

shell腳本及shell編程:當命令或程序語句不在命令行下執行,而是經過一個程序文件來執行時,該程序就被稱爲shell腳本,編寫shell腳本的過程就稱爲shell編程工具

 

 

2.shell腳本的編寫

(1)hello world

shell腳本通常可使用vi編輯器或emacs編輯器編寫,上述代碼中第一行是聲明腳本運行方式,在shell腳本中以#開頭的爲註釋,不會被執行

 

(2)shell腳本的基本構成

運行結果以下:

以上代碼的部份內容解釋:

  • 以#開頭的爲註釋
  • echo爲輸出語句,參數-n表示在顯示信息時不自動換行
  • whoami命令字符串左右的反引號(`)用於命令替換(轉換),也就是將它所括起來的字符串視爲命令執行,並將其輸出的字符串在原地輸出

 

(3)在shell腳本中包含外部腳本

1 . 腳本文件名
2 source 腳本文件名

實例:

注:上述代碼中最後一行中的第二個.號表示當前目錄

 

 

3.shell腳本的執行與調試

(1)執行

在命令行下直接執行:

1 chmod +x example
2 ./example [參數]

 

在指定的shell下執行腳本:

1 shell名稱 腳本名 [參數]
2 sh hello.sh
3 bash hello.sh

 

(2)調試

1 bash -v 腳本名
2 bash -x 腳本名

 

 

 

2、shell變量

1.變量類型

  • 用戶自定義變量(局部變量):由用戶在shell程序中自定義
  • 環境變量:系統環境中的一部分,沒必要去定義,能夠在shell程序中使用,某些變量(如PATH)能夠在shell中修改
  • 內部變量:linux系統提供的一種特殊類型的變量,此類變量在程序中用來作出判斷

注:常見的內部變量

1 $# 傳送給shell程序的位置參數的數量
2 $? 最後命令的完成碼或在shell程序內部執行的shell程序的返回值
3 $0 shell程序的名稱
4 $* 調用shell程序時所傳送的所有參數組成的單字符串

 

 

2.變量賦值和訪問

(1)變量定義及賦值

  • 變量定義:變量名=值
  • 變量賦值:變量2=$變量1

注:定義變量時變量名不需加$,在賦值符號兩邊不容許有任何空格;變量名由字母、數字、下劃線組成,能夠由字母和下劃線開頭

 

把一個命令的結果做爲變量的內容賦值的方法:

1 變量名=`ls`   # 不推薦使用這種方法,由於容易和單引號混淆  
2 變量名=$(ls)  # 把命令用$()括起來,推薦使用這種方法

 

(2)變量訪問:在變量名前加上一個$

$變量名錶示輸出變量,能夠用$c和${c}兩種語法

注意在一些場合中訪問變量值時必須爲變量名加上花括號{}

注:若是不給此時的skill加花括號,解釋器會將skillScript當成一個變量,因爲沒有爲這個變量賦值,其值爲空。因此在字符串給因此變量加上花括號是一個好的編程習慣!

 

(3)只讀變量和刪除變量

  • 使用readonly命令設置只讀變量,只讀變量的值不可改變
  • 使用unset命令刪除變量,變量被刪除後不能再次使用,unset不能刪除只讀變量

 

(4)添加環境變量

使用export命令將變量添加到環境變量中,做爲臨時的環境變量(一種全局變量)

基本語法:export 變量名=變量值

注:export命令僅將變量加到環境中,若是要從程序的環境中刪除該變量,則可使用unset命令或env命令,env也能夠臨時地改變環境變量值

 

 

3.內部變量

變量 含義
$0 腳本名
$1 -$9 位置參數1-9
${10} 位置參數10
$# 位置參數的個數
"$*" 全部位置參數(做爲單個字符串)
"$@" 全部位置參數(每一個做爲單獨字符串)
${#*} 傳遞到腳本中的命令行參數的個數
${#*} 傳遞到腳本中的命令行參數的個數
$? 返回值
$$ 腳本進程的PID
$- 傳遞到腳本中的標識
$_ 以前命令的最後一個參數
$! 運行在後臺的最後一個做業的進程ID(PID)

 

 

4.位置參數

  • $0:獲取當前執行的腳本文件名
  • $n:獲取當前執行的腳本的第n個參數,n=1...9,當n>10時就要用大括號括起來,例如:${10}
  • $#:獲取當前執行的腳本後面接的參數的總數
  • $*:獲取當前執行的腳本全部傳參的參數
  • $@:獲取當前執行的腳本全部傳參的參數

 

 

5.變量值的輸出與讀取

(1)echo命令(加上-n選項表示不換行輸出)

1 str="OK!"
2 echo $str # 直接輸出指定的字符串
3 echo "$str This is a test" # 將變量混在字符串中輸出
4 
5 mouth=4
6 echo "2018-${mouth}-3" # 將變量混在字符串中輸出若是要將變量和其餘字符鏈接在一塊兒,就要使用花括號進行變量替換

 

(2)printf命令

1 printf格式:printf 格式字符串 [參數列表...]
2 
3 printf "hello! \n"
4 printf "%d %s\n" 100 "abc"

 

(3)read命令

1 read格式: read 變量
2 注:-p選項定義提示語句,-n選項對輸入的字符進行計數,當輸入的字符達到預約數目時自動退出,並將輸入的數據複製給變量
3 
4 read str
5 read -p "請輸入兩個數字" n1 n2

 

注:關於單引號、雙引號、反引號的知識說明

單引號:關閉shell中全部的特殊符號使用和解釋。說的簡單點,就是單引號(‘ ’)中間的全部內容都做爲普通的字符輸出,就是說無論你是否是一些特殊的字符(如$,轉移字符等)通通做爲普通字符輸出

雙引號:關閉shell中的大部分的特殊字符,但保留部分,如$、轉義字符\ (不包括\n \t等)、反引號(` `),而單引號(' ')則失效,做爲普通字符輸出

反引號:將反引號(` `)內的字符串看成shell命令來執行,返回值是命令的執行的結果,起到的是一個命令的替換做用

 

 

6.變量替換

變量替換根據變量的狀態(是否爲空是否認義)來改變它的值,使用花括號限定一個變量的開始和一個變量的結束

  • ${var}:替換爲變量原本的值
  • ${var:-word}:若是變量var爲空或已被刪除,則返回word,但不改變var的值
  • ${var:=word}:若是變量var爲空或已被刪除,則返回word,並將var的值設置爲word
  • ${var:?message}:若是變量var爲空或已被刪除,則將消息message發送到標準錯誤輸出,能夠用來檢測變量var是否能夠被正常賦值
  • ${var:+word}:若是var被定義,則返回word,但不改變var的值

 

 

7.數組

數組中能夠存放多個值。Bash Shell 只支持一維數組(不支持多維數組),初始化時不須要定義數組大小(與 PHP 相似),與大部分編程語言相似,數組元素的下標由0開始

Shell 數組用括號來表示,元素用"空格"符號分割開,語法格式以下:array_name=(value1 ... valuen)

數組實例:

 

 

 

3、表達式與運算符

1.表達式

expr命令:是一款表達式計算工具,使用它完成表達式的求值操做

let命令:計算整數表達式的值

expr命令使用:

1 expr 5 +3
2 
3 n=1
4 m=5
5 expr $n + $m
6 
7 val=`expr 2 +2`

let命令使用:

1 n=1
2 m=5
3 let val=$n+$m
4 # 注意這種形式要求運算符和操做數之間不能有空格!

 

test命令:判斷表達式的真假

1 test使用:test 邏輯表達式
2 test "abc"="xyz"

 

 

2.運算符

 1 (1)算術運算: + - * / % =
 2 
 3 (2)整數關係運算符: 
 4 -eq 相等
 5 -ne 不等於
 6 -gt 大於
 7 -lt  小於
 8 -ge 大於等於
 9 -le 小於等於
10 
11 (3)字符串檢測運算符: 
12 =  檢測兩個字符串是否相等,相等返回true
13 != 檢測兩個字符串是否相等,不等返回true
14 -z 檢測字符串長度是否爲0,爲0返回true
15 -n 檢測字符串長度是否爲0,不爲0返回true
16 str 檢測字符串是否爲空,不爲空返回true
17  
18 (4)文件測試運算符 - 省略
19 
20 (5)布爾運算符
21 -a 與  兩個表達式均爲true才返回true
22 -o 或  有一個表達式爲true才返回true
23 ! 非  表達式值爲true返回false不然返回true

 

 

 

4、分支循環語句

1.if語句

(1)if結構

1 if [ 條件表達式 ]
2 then
3 語句序列
4 fi

注:條件表達式和[]之間必須有空格,不然會出現語法錯誤

if結構實例:

1 # !/bin/bash
2 a=1
3 b=2
4 if [ $a -lt $b ]
5 then
6     echo "a小於b"
7 fi

 

(2)if...else結構

1 if [ 條件表達式 ]
2 then
3     語句序列1
4 else
5     語句序列2
6 fi

if...else結構實例:

1 # !/bin/bash
2 a=1
3 b=2
4 if [ $a -lt $b ]
5 then 
6     echo "a小於b"
7 else
8     echo "a不小於b"
9 fi

 

(3)if..elif...else結構

 1 if [ 條件表達式1 ]
 2 then
 3     語句序列1
 4 elif [ 條件表達式2 ]
 5 then
 6     語句序列2
 7 elif [條件表達式3]
 8 then
 9     語句序列3
10 ...
11 else
12     語句序列n
13 fi

if..elif...else結構實例:

 1 # !/bin/bash
 2 a=1
 3 b=2
 4 if [ $a == $b ]
 5 then
 6     echo "a等於b"
 7 elif [ $a -gt $b ]
 8 then 
 9     echo "a大於b"
10 elif [ $a -lt $b ]
11 then 
12     echo "a小於b"
13 else
14     echo "全部條件均不知足"
15 fi

 

 

2.case語句

 1 case 值 in 
 2 模式1)
 3 語句序列1
 4 ;;
 5 模式2)
 6 語句序列2
 7 ;;
 8 ......
 9 模式n)
10 語句序列n
11 ;;
12 *)
13 其餘語句序列
14 esac

實例:

 1 # !/bin/bash
 2 case $USER in
 3 whxy)
 4   echo "歡迎登陸"
 5 ;;
 6 root)
 7   echo "超級管理員!"
 8   echo "熱烈歡迎"
 9 ;;
10 *)
11   echo "歡迎 $USER !"
12 ;;
13 esac

 

 

3.循環語句

(1)while語句

1 while 測試條件
2 do
3 語句序列
4 done

實例:用while循環求1到100的和

1 # !/bin/bash
2 total=0
3 num=0
4 while [ $num -le 100 ]
5 do 
6     total=`expr $total + $num`
7     num=`expr $num + 1`
8 done 
9 echo "結果等於: $total"

 

(2)until語句

1 until 測試條件
2 do 
3 語句序列
4 done

實例:用until循環求1到100的和

1 # !/bin/bash
2 total=0
3 num=0
4 until [ $num -gt 100 ]
5 do
6     total=`expr $total + $num`
7     num=`expr $num + 1`
8 done
9     echo "計算結果爲: $total"

 

(3)for語句

 1 for 變量 [ in 列表 ]
 2 do
 3     語句序列
 4 done
 5 
 6 eg:
 7 # 循環輸出
 8 for var in 1 2 3 4 5 6 
 9 do 
10     echo $var
11 done
12 
13 # 顯示主目錄下的文件
14 for FILE in $HOME/*.*
15 do 
16     echo $FILE
17 done

 

 

4.break和continue和exit

  • break:退出循環
  • continue:退出當前循環繼續下次循環
  • exit:退出一個shell程序

另外上述3種均可以指定值,例如break [3]就是退出3層循環,continue [2]表示跳出2層循環,exit [2]表示指定退出值爲2

 

 

 

5、函數

1.函數的定義和調用

(1)函數的定義

1 [function] 函數名()
2 {
3 命令序列
4 [return 返回值]
5 }

function和return能夠省略不寫

 

(2)函數的調用

函數的調用:函數名 參數1 參數2 ...... 參數n

 

(3)實例

1 # !/bin/bash
2 Hello(){
3 echo "Hello world!"
4 }
5 Hello  # 調用函數

 

 

2.函數的返回值

(1)return

shell函數的返回值,能夠和其餘語言的返回值同樣,經過return語句返回。
示例:

 1 #!/bin/bash
 2 function test()  
 3 {  
 4     echo "arg1 = $1"   # 輸出第一個參數
 5     if [ $1 = "1" ]
 6     then  
 7         return 1  
 8     else  
 9         return 0  
10     fi  
11 }  
12   
13 echo "test 1:"  
14 test 1  
15 echo $?         # print return result  
16   
17 echo "test 0:"  
18 test 0  
19 echo $?         # print return result  
20   
21 echo "test 2:"  
22 test 2  
23 echo $?         # print return result  

 

(2)echo

其實在shell中,函數的返回值有一個很是安全的返回方式,即經過輸出到標準輸出返回。由於子進程會繼承父進程的標準輸出,所以,子進程的輸出也就直接反應到父進程。

示例:

 1 #!/bin/bash
 2 function test()  
 3 {  
 4     echo "arg1 = $1"  
 5     if [ $1 = "1" ] 
 6     then  
 7         echo "1"  
 8     else  
 9         echo "0"  
10     fi  
11 }  
12   
13 echo "test 1"  
14 test 1  
15 
16 echo "test 0"  
17 test 0  
18 
19 echo "test 2"  
20 test 2  

注:不能向標準輸出一些不是結果的東西(也就是不能隨便echo一些不須要的信息),好比調試信息,這些信息能夠重定向到一個文件中解決,特別要注意的是,腳本中用到其它相似grep這樣的命令的時候,必定要記得1>/dev/null 2>&1來空這些輸出信息輸出到空設備,避免這些命令的輸出

 

 

3.函數的參數

1 shell中調用函數時能夠向其傳遞參數,與腳本同樣,在函數體內部是經過$n的形式來獲取參數的值
2 好比$1表明第一個參數,$2表明第二個參數

 

 

4.函數實戰

(1)計算階乘

1 設計一個shell程序計算n的階乘。要求:
2 從命令行接收參數n;
3 在程序開始後當即判斷n的合法性,便是否有參數,如有是否爲正整數,若非法請給錯誤提示;
4 最後輸出計算的結果

代碼實現:

 

 

(2)

 

 

(3)

相關文章
相關標籤/搜索